לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תכנות ובניית אתרים
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 05-09-2008, 14:51
צלמית המשתמש של High_Hopes
  משתמש זכר High_Hopes High_Hopes אינו מחובר  
 
חבר מתאריך: 30.05.02
הודעות: 8,838
עזרה בC, שיעורי בית ברקורסיה

שלום חברים. קיבלנו תרגיל בC שכלל כמה סעיפים, הצלחתי לפתור את כלום חוץ מאחד:
אני צריך לכתוב פונקציה רקורסיבית שמקבלת שתי מחרוזות (בגודל זהה, אך לא חובה שמשתמשת בכל הגודל), הפונקציה מכניסה למחרוזת השנייה את התוכן ההפוך של המחרוזת הראשונה.
לדוגמא:str1="Hello World"
צריך לגרום לכך שבמחרוזת השנייה יופיע "dlroW olleH"
ההכרזה על הפונקציה חייבת להיראות ככה:
void strReverse(char*,char*)
אסור להוסיף משתנים להרכזה, אסור להשתמש בפונקציות אחרות (לדוגמא, פונקציה שמוצאת אורך מחרוזת) אסור להשתמש במשתנה סטטי או בDefine.
בקיצור, זה חייב להיות רקורסיבי בלבד
כמובן שצריך להוסיף '\0'בסוף המחרוזת
מותר להשתמש בפונקציות ספריה של stdio.h ושל conio.h

אני כבר שובר את הראש מהפונקציה הזאת, אני יודע שזה לא כל כך מסובך אבל זה פשוט לא מצליח לי, אשמח לעזרה בכיוון לפתרון (גם פתרון יהיה לא רע בכלל, אבל אני מעדיף לנסות לבד).

תודה מראש.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה
הגלריה שלי בפליקר

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #6  
ישן 05-09-2008, 16:59
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 5 שנכתבה על ידי High_Hopes שמתחילה ב "הוא לא הגדיר שלא, אבל אני..."

אני לא רואה דרך נוספת שכן אתה זקוק למידע נוסף שאתה לא יכול להעביר על מחסנית הקריאות.
הרעיון שלי היה בערך כזה:
הנתון החשוב פה הוא שאורכי המחרוזות שאתה מקבל כפרמטרים שווים מלחתחילה.

בכל אופן, הבעיה העיקרית היא שב'משחק' הפויינטרים אתה צריך להתקדם בכל מחרוזת לכיוון שונה - במחרוזת המקור אתה מתקדם מההתחלה לסוף ובמחרוזת היעד מהסוף להתחלה (או להיפך).

כדי שזה יקרה, אתה צריך מידע שאתה לא יכול להעביר על המחסנית, לכן נאלץ לעשות מניפולציה קטנה:
תנאי סיום הרקורסיה: הגענו לסוף מחרוזת היעד (הנתון החשוב)
תחילת הרקורסיה תהיה לולאה שתרוץ עד לסוף מחרוזת המקור.
כעת אתה מעביר את התו האחרון לתחילת היעד.
כעת אתה רוצה לבטל תווים שכבר ניצלנו - לכן אתה כותב \0 במקום התו שכרגע כתבת...
ועכשיו אתה מתקדם במשחקי פויינטרים מהסוף להתחלה במחרוזת המקור ומההתחלה לסוף במחרוזת היעד...

פתרון בקוד:
זהירות - ספויילר!
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #7  
ישן 05-09-2008, 18:01
צלמית המשתמש של High_Hopes
  משתמש זכר High_Hopes High_Hopes אינו מחובר  
 
חבר מתאריך: 30.05.02
הודעות: 8,838
בתגובה להודעה מספר 6 שנכתבה על ידי Dark Knight שמתחילה ב "אני לא רואה דרך נוספת שכן אתה..."

תודה רבה על ההשקעה.

זה בהחלט פותר את השאלה, רק יש שתי בעיות:
א. זה לא שם null בסוף המחרוזת (המחרוזת היא בגודל 256, אם אני מכניס מחרוזת של 16 תווים אני צריך NULL במקום ה17)
ב. זה מוחק את המחרוזת המקורית, שכפי שאמרתי, אני לא בטוח שזה בעיה או לא.

בכל מקרה זה הרבה יותר טוב ממה שהצלחתי להגיע אליו עד עכשיו, אם לא נמצא שום דבר אחר אני אעזר בזה.

חשבתי על רעיון קצת מוזר, לא יודע אם אפשר ליישם אותו - בascii יש 255 תווים (אם מורידים את NULL), אולי אני יכול להעזר במחרוזת השנייה על ידי הכנסת תווי אסקי לתוכה וככה אני יכול לבנות קאונטר בתוך המחרוזת. הבעיה שאני מסתכן בזה שאני מכניס "זבל" לתוך המחרוזת.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה
הגלריה שלי בפליקר

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #8  
ישן 05-09-2008, 18:22
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 7 שנכתבה על ידי High_Hopes שמתחילה ב "תודה רבה על ההשקעה. זה בהחלט..."

הסתמכתי על הנתון שהקלט הוא 2 מחרוזות באורך שווה => בשניהם תו ה-0\ נמצא באותו המקום.
לכן אין צורך לטפל בו באופן מיוחד...

גם אני חשבתי על רעיון של שימוש בבית או ב-4 הבתים הראשונים כמונה, אולם זה פתרון בעייתי שכן א': אתה תדרוס בסופו של דבר את המונה שלך והמידע יאבד, ו-ב' אי אפשר להניח דבר על אורך המחרוזת...
אם תקבל מחרוזת באורך 1 כשאתה עובד על 4 בתים אתה מסתכן ב-segmentation fault, ואם אתה עובד עם בית אחד אתה לא תוכל לטפל במחרוזות באורך של למעלה מ-256 תווים...
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #13  
ישן 05-09-2008, 16:36
  rtasjugyth rtasjugyth אינו מחובר  
 
חבר מתאריך: 29.08.08
הודעות: 97
נסה משהו כזה:
בתגובה להודעה מספר 1 שנכתבה על ידי High_Hopes שמתחילה ב "עזרה בC, שיעורי בית ברקורסיה"

לפני זה, קטע קטן:
הקריאה הרקורסיבית יכולה להימצא בכל מיני מקומות בקוד. לרגע בוא נתעלם מקוד מורכב בתוך הפונקציה, ונחשוב על שני מקרים פשוטים - אתה עושה משהו עם הנתונים שלך, ואז מבצע את הקריאה הרקורסיבית, או שאתה מבצע את הקריאה הרקורסיבית, ואז עושה את מה שבא לך לעשות.
זה נשמע קצת אנטי-אינטואטיבי, אבל לפעמים צריך לחשוב על הדרך השנייה, כדי למצוא את הפיתרון. ב-merge sort לדוגמה, משתמשים בצורה השנייה. הדרך שבה רקורסיה כזו עובדת היא שאתה נכנס לעומק מחסנית הקריאות, ואז ביציאה, עושה את מה שאתה רוצה לעשות.
שוב, אני אדגיש, הפעולה העיקרית של הפונקציה שלך נעשית ביציאה ממחסנית הקריאות.

הבעיה שלך היא המגבלה המלאכותית שהוסיפו בתרגיל - שאתה לא יודע את אורך המחרוזות. אסור לך להשתמש ב-strlen. לכן, אתה לא יכול להשתמש בפיתרון כמו זה ש-rlsf הציע - כי אתה לא יודע איפה נמצא התו האחרון (הוא נמצא ב-str1[len-1]‎, אבל אתה לא יודע מהו len).
אסור לך ללכת עד ה-NULL כדי לגלות את אורך המחרוזת, זה שקול לקריאה ל-strlen.

אז מה אתה יכול לעשות?

יש קטגוריה של פיתרונות רקורסיביים שבהם מבצעים פעולה על חלק ממערך (לדוגמה, ההתחלה), ואז קוראים לעצמך רקורסיבית על שאר המערך. לדוגמה, אתה רוצה להכפיל כל מספר בערך פי 2 - אתה מכפיל את המספר הראשון במערך פי 2, וקורא לעצמך על המערך ללא התו הראשון:
קוד:
void doubleArray(int*arr, size_t size) { if (size == 0) return; arr[0] = arr[0] * 2; doubleArray(arr+1, size-1); };


אתה הולך לעשות משהו דומה, לעבור תו-תו כשכל תו נעשה בקריאה אחרת. ההבדל הוא שאתה רוצה להתחיל מסוף המחרוזת, ובשביל זה תצטרך לדעת מה הגודל שלה. היופי הוא שכשתגיע לעומק מחסנית הקריאות, אתה גם תדע מה אורך המחרוזת. תיכנס רקורסיבית עד שתגיע לסוף המחרוזת (זה מותר), ועכשיו ביציאה אתה יודע מה אורך המחרוזת, ומסוגל לבצע את ההחלפה.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 14:39

הדף נוצר ב 0.06 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר