• הודעות
  • אשכולות
  • רשומים
  • לייקים
  • מחוברים כרגע
הרשמה לאתר הרשמה באמצעות facebook
עמוד 1 מתוך 2 12 אחרוןאחרון
תגיות: קשה, רקורסיה
C|

רקורסיה קשה רצח :/ בבקשה עזרה פה

  1. 20-12-2010 06:11 #1
    197
    12-12-07
    בן
    כתוב פונקציה רקורסיבית void check_zone(int nums[][M], int x, int y, int num) המקבלת כפרמטר מערך דו-ממדי של מספרים שלמים מ-1 עד 5 בגודל N שורות ו- M עמודות אשר הוגדרו ב-define , הקואורדינטות של איבר בתוך המערך והמספר שמופיע בקואורדינטות אלה .
    בבמקום הזה יש מספר בין 1 ל-5. הפונקציה צריכה להדפיס את כמות המספרים הזהים בתוך המערך שמהווים אזור רציף שכולל את המספר הזה.
    דוגמא:
    אם היא מקבלת את המערך :
    4 3 2 3 1
    5 3 3 2 2
    1 1 3 3 2
    1 3 3 2 4
    5 5 3 4 4
    אם הקואורדינטות הםא 3,2 ואז המספר הוא 3 ותדפיס 9 ( נא לשים לב שיש אזור רציף נוסף למספר 2)
    אם הקואורדינטות הםא 4,0 ואז המספר הוא 4 ותדפיס 3 ( נא לשים לב שיש 4 נוסף אבל הוא לא באזור רציף, כנ"ל יכול להיות עם 5 ו-1 )


    לפתרון התרגיל חשבתי על לעשות פונקציה אחת רגילה אשר תבדוק עבור הקורדינטות שניתנו אם ישנו איבר סמוך מכל כיוון אפשרי הזזה בגודלו, במידה ויש זיהוי של איבר סמוך זהה אנו נגיד לפונקציה להחזיר את הפונקציה השניה שהיא רקורסיבית אשר תבדוק כמה איברים סמוכים ישנם.
    אבל יש לי בעיה קטנה עם המשחק הזה של סריקת האיברים הסמוכים, אני רוצה לעשות זאת בצורה מסביב לקורדינאטה זאת אומרת עבור הקורדינאטה של, 3.2 אני יתחיל לבדוק את האיבר 2,1 ולאחר מכאן 2,2 ואז 2,3 ואז ירד שורה ל, 3,3 ואז 4,3 ואז 4,2 ן 4,1 ולבסוף 3,1.
    במידה ועבור אחת הקורדינטות שנבדקו נמצא כי יש איבר סמוך דומה, אני עובר לקורדינטה שעבורה מצאנו גילוי וחוזר על התהליך.
    כמובן שיש איזה קאונטר שסופר את מספר הגילויים פלוס אחד בשביל להכניס את הקורדינטה המקורית לסכום הגילויים.
    רק שאני לא מצליח לרשום את הרצונות שלי בקוד :/
    אפשר עזרה עם זה?
    נערך לאחרונה על ידי sapir_123, 20-12-2010 בשעה 06:41

  2. 20-12-2010 12:15 #2
    8,977
    1
    03-01-09
    בן
    למה אתה קורא "רציף"? מספרים עולים (או יורדים) ב-1? רצף מספרים זהה? שכנים בלבד? אם כן, כולל אלכסונים? לפי הדוגמה הראשונה שלך, אתה מדפיס את מספר ההופעות של המספר במטריצה, שזה 9.

  3. 20-12-2010 14:19 #3
    115
    1
    17-12-10
    בן
    אתה בטוח שזה צריך להיות void? זה לא אפשרי כך כך בקלות לפי איך שנראה לי.. הינה פיתרון עם פונקציה שמחזירה את הערך..:


    קוד:
    int check_zone(int nums[N][M], int x, int y, int num) 
    
    { int a,b,c,d,e,f,g,h; if((x>=0)&&(x<=N-1)&&(y>=0)&&(y<=M-1)&&(nums[x,y]==num)) { nums[x][y]=num+1;
    a=check_zone(nums[N][M], x+1, y, num); b=check_zone(nums[N][M], x-1, y, num); c=check_zone(nums[N][M], x, y+1, num); d=check_zone(nums[N][M], x, y-1, num); e=check_zone(nums[N][M], x+1, y+1, num); f=check_zone(nums[N][M], x-1, y+1, num); g=check_zone(nums[N][M], x+1, y-1, num); h=check_zone(nums[N][M], x-1, y-1, num); return 1+a+b+c+d+e+f+g+h; } return 0;
    }
    נערך לאחרונה על ידי lokookol, 20-12-2010 בשעה 18:42

  4. 20-12-2010 17:42 #4
    197
    12-12-07
    בן
    כן הם יכולים להיות גם אלכסוניים.
    הפונקציה הזו לא מחסה את האופציה של האלכסונים, וגם הוא בודקת רק את כל השורה או העמודה, מה קורה במצב שבוא גם לשורה או העמודה הנבדקת יש איבר סמוך זהה?

  5. 20-12-2010 18:38 #5
    115
    1
    17-12-10
    בן
    ציטוט פורסם במקור על ידי sapir_123 צפה בהודעה
    כן הם יכולים להיות גם אלכסוניים.
    הפונקציה הזו לא מחסה את האופציה של האלכסונים, וגם הוא בודקת רק את כל השורה או העמודה, מה קורה במצב שבוא גם לשורה או העמודה הנבדקת יש איבר סמוך זהה?

    תיקנתי את זה בשביל שיבדוק גם אלכסונים..

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

    אז אם לראשון, בדקנו לכל 8 הכיוונים, גם לאיבר הבא, כל אחד מה-8 האלה, נבדוק בשבילו גם ל-8 כיוונים..
    ולכן התוכנית הזאת נכונה.

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

    מקווה שהבנת. שאל אם לא..
    נערך לאחרונה על ידי lokookol, 20-12-2010 בשעה 18:40

  6. 20-12-2010 19:59 #6
    197
    12-12-07
    בן
    לא הבנתי איך בידיוק אתה מונע ספירה נוספת של האיבר ממנו הוא הגיע.

  7. 20-12-2010 20:02 #7
    115
    1
    17-12-10
    בן
    אחרי ספירה ראשונה של האיבר, אני משנה את הערך שלו!

    קוד:
    nums[x][y]=num+1;
    ואז כשהוא יגיע אליו בפעם השניה/שלישית וכו'.. - לא יהיה לא את הערך שצריך,והוא יחזיר אפס,ידלגו עליו..

  8. 20-12-2010 20:12 #8
    197
    12-12-07
    בן
    אבל אז אתה פוגע הערך של המערך המקורי, אסור לשנות אותו.

  9. 20-12-2010 20:31 #9
    115
    1
    17-12-10
    בן
    אז אפשר לעשות מטריצה בוליאנית בצד שאחרי כל איבר שעברתי עליו, היא משנה לTRUE..

  10. 20-12-2010 20:45 #10
    197
    12-12-07
    בן
    קוד:
    	int boliani[M][N]={0};
    	   if((x>=0)&&(x<=N-1)&&(y>=0)&&(y<=M-1)&&(arr[x][y]==num)&&(boliani[x][y]==0))
    	   {
    
             boliani[x][y]=num+1;
    לזה התכוונת?

  11. 20-12-2010 21:27 #11
    115
    1
    17-12-10
    בן
    קוד:
    int check_zone(int nums[N][M], int x, int y, int num) 
     
    
    { int a,b,c,d,e,f,g,h; static int washere[N][M]={0}; if((x>=0)&&(x<=N-1)&&(y>=0)&&(y<=M-1)&&(nums[x,y]==num)&&(!washere[x][y])) { washere[x][y]=1; a=check_zone(nums[N][M], x+1, y, num); b=check_zone(nums[N][M], x-1, y, num); c=check_zone(nums[N][M], x, y+1, num); d=check_zone(nums[N][M], x, y-1, num); e=check_zone(nums[N][M], x+1, y+1, num); f=check_zone(nums[N][M], x-1, y+1, num); g=check_zone(nums[N][M], x+1, y-1, num); h=check_zone(nums[N][M], x-1, y-1, num); return 1+a+b+c+d+e+f+g+h; } return 0; }
    בדרך הזאת, המערך החדש שיצרתי, מאותחל רק פעם אחת כי הוא סטטי, וכל איבריו בהתחלה שווים לאחד. האיבר במערך שאני צריך לבדוק, נבדק רק אם מקומו במערך החדששווה ל-0.אם לא - סימן שכבר נבדק, ומדלגים עליו. בדרך זו אני בעצם בודק בדיוק את מה שהיה לי לפני, רק לא משנה את הערכים במערך המקורי.

    מקווה שהבנת

    בהצלחה!!
    נערך לאחרונה על ידי lokookol, 21-12-2010 בשעה 03:29

  12. 21-12-2010 00:37 #12
    197
    12-12-07
    בן
    מה אומר הסטטיק?
    int static washere[N][M]={0};
    נערך לאחרונה על ידי sapir_123, 21-12-2010 בשעה 00:38

  13. 21-12-2010 00:46 #13
    115
    1
    17-12-10
    בן
    הסטטיק אומר שהמשתנה יוגדר רק בפעם הראשונה שניכנס לפונקציה. פעם הבעיה שנכנס לפונקציה (הרי היא ריקורסיה) הוא לא יגידר את המערך הזה מחדש, הרי הוא כבר קיים. סטטיק משמעו שהחיים שלו הם כל התוכנית. ולא רק לוקלית לפונקציה הזאת- היא גלובלית. משמע, לא כל פעם נגדיר מערך שערכיו 0. אלא בפעם הראשונה, ואז בגלל שזה סטטיק, זה לא יגדיר אותו שוב. הבנת?

  14. 21-12-2010 02:47 #14
    197
    12-12-07
    בן
    צריך להגדיר משתנה מסוג זה איפה שאני מגדיר משתנים גלובליים או שאפשר גם כחלק מהפונקציה.

    IntelliSense: identifier "washere" is undefined
    מופיע לי הודעת שגיאה כזו והתכנית ראשית רצה טוב מלבד האפשרות של הפעלת הפונקציה.

  15. 21-12-2010 03:00 #15
    115
    1
    17-12-10
    בן
    צריך בדיוק איך שעשיתי. רק טעות אחת - הסטטיק בא לפני האינט, כך:
    קוד:
    static int washere[N][M]={0};
    זה משתנה רגיל לכל דבר. רק סטטיק אומר שהוא לא ימחק כשתצא מהקריאה הזאת של הפונקציה. נשמר לו מקום בזיכרון, בהגדרה הראשונה שלו - וגם כשיגיע לשורה של להגדיר את עצמו שוב (בריקורסיה - בקריאה השנייה) הוא לא יגדיר את עצמו - כי כבר יש לו כתובת בזיכרון. זה אותו משתנה - סטטיק.

עמוד 1 מתוך 2 12 אחרוןאחרון
מקרא דרגות:  » יו"ר » מנכ"ל » מנהל ראשי » מפקח » מנהל פורום » צוותי האתר » משתמש כבוד » היכל התהילה » Champ » משקיען כבוד » Winner