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

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

  1. 20-12-2010 06:11 #1
    בן
    תאריך הצטרפות
    12-12-07
    הודעות
    197
    כתוב פונקציה רקורסיבית 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
    בן
    תאריך הצטרפות
    03-01-09
    הודעות
    8,977
    למה אתה קורא "רציף"? מספרים עולים (או יורדים) ב-1? רצף מספרים זהה? שכנים בלבד? אם כן, כולל אלכסונים? לפי הדוגמה הראשונה שלך, אתה מדפיס את מספר ההופעות של המספר במטריצה, שזה 9.

  3. 20-12-2010 14:19 #3
    בן
    תאריך הצטרפות
    17-12-10
    הודעות
    115
    אתה בטוח שזה צריך להיות 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
    בן
    תאריך הצטרפות
    12-12-07
    הודעות
    197
    כן הם יכולים להיות גם אלכסוניים.
    הפונקציה הזו לא מחסה את האופציה של האלכסונים, וגם הוא בודקת רק את כל השורה או העמודה, מה קורה במצב שבוא גם לשורה או העמודה הנבדקת יש איבר סמוך זהה?

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

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

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

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

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

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

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

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

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

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

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

  10. 20-12-2010 20:45 #10
    בן
    תאריך הצטרפות
    12-12-07
    הודעות
    197
    קוד:
    	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
    בן
    תאריך הצטרפות
    17-12-10
    הודעות
    115
    קוד:
    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
    בן
    תאריך הצטרפות
    12-12-07
    הודעות
    197
    מה אומר הסטטיק?
    int static washere[N][M]={0};
    נערך לאחרונה על ידי sapir_123, 21-12-2010 בשעה 00:38

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

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

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

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

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