עבור לתוכן

שאלה : עזרה בפיתרון תרגיל.

Featured Replies

פורסם

אהלן,

תרגיל: כתוב פונקציה רקורסיבית לחישוב סכום איברי מערך דו-מימדי. (C#)

למישהו יש מושג איך ניתן לכתוב דבר כזה?

פורסם

מומלץ שתערוך את הכותרת כך שתכיל יותר מידע (רקורסיה, #C).

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

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

פורסם
  • מחבר

הגעתי לפיתרון,

אבל הוא נראה לי קצת משונה - אני בעצם קורא לפונ' הרקורסיבית בשני מצבים:

ניתן לשפר?

void Func(int iarrnArr[ROWS][COLS], int inRowIndex, int inColIndex, int* ionSum)
{
// Code Section

*(ionSum) += iarrnArr[inRowIndex][inColIndex];

if (inRowIndex < (ROWS - 1))
{
++inRowIndex;
Func(iarrnArr, inRowIndex, inColIndex, ionSum);
}
else
{
inRowIndex = 0;

if (inColIndex < (COLS - 1))
{
++inColIndex;
Func(iarrnArr, inRowIndex, inColIndex, ionSum);
}
}
}

פורסם

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

++inRowIndex;
if (inRowIndex == ROWS) {
inRowIndex = 0;
++inColIndex;
}
if (inColIndex < COLS) {
// recursive call here
}

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

נ.ב. לא הבנתי, התכנית שלך היא ב-C או ב-#C?

(לא שזה משנה במיוחד, פשוט הקוד שלך נראה כאילו הוא כתוב ב-C)

פורסם
  • מחבר

קודם כל תודה!

דבר שני, כן בסוף כתבתי בC++..

אבל בגדול כל מה ששונה זה הכותרת של הפונקציה (הרשאת הגישה) לא?

בכל נוסף, ניסיתי לחשוב איך לא להעביר את הסכום כפרמטר.. לא הצלחתי.

פורסם

אין מצביעים ב-#C. אם היית כותב ב-#C אז היית צריך להעביר את הסכום כ-ref, ואת המערך כ-[][]int.

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

פורסם
  • מחבר

נכון שכחתי :xyxthumbs:

בקשר למצביעים.

בד"כ כשאני רוצה לשלוח פרמטר in/out - כלומר גם חשוב לי הערך שאיתו הוא נשלח וגם הערך שאיתו הוא חוזר

אני צריך להשתמש ב - out ולא ב- ref.

אני טועה?

ו.. הנה התיקון. משום מה התוצאה הסופית איננה נכונה.. איפסתי את המערך 4*5 רק בספרה 1 (כלומר הסכום הוא 20)

והתוצאה המחוזרת היא 23.

לא עליתי על הבעיה.

int Func(int iarrnArr[ROWS][COLS], int inRowIndex, int inColIndex)
{
// Code Section

++inRowIndex;

if (inRowIndex == ROWS)
{
inRowIndex = 0;
++inColIndex;
}

if (inColIndex < COLS)
{
return((iarrnArr[inRowIndex][inColIndex]) + (Func(iarrnArr, inRowIndex, inColIndex)));
}
}

פורסם

לא הבנתי את השאלה שלך. ב-#C משתמשים ב-out (קיצור ל-output) כאשר הפונקציה לא אמורה להשתמש בערך של הפרמטר שהועבר לה, וב-ref (קיצור ל-reference) כשהפונקציה כן צריכה להשתמש באותו ערך.

הבעיה בתכנית שלך היא שאתה מוסיף את האיבר הבא במערך לסכום, ולא את האיבר הנוכחי. תחשוב מה קורה כשאתה קורא לפונקציה עם inRowIndex==0 ו-inColIndex==0.

פורסם
  • מחבר

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

אבל גם את הסכום של התא הנוכחי. אין לי מושג איך לאחד \ ליצור מהלך הגיוני.

נ.ב. מה קורה מצב שאני רוצ להעביר פרמטר שחשוב לי גם הערך שהוא נכנס וגם הערך שיוצא (גם ref וגם out)?

פורסם

אז שיהיה ref.

ולגבי הרקורסיה:

int Func(int iarrnArr[ROWS][COLS], int inRowIndex, int inColIndex)
{
// Code Section
int currentValue = iarrnArr[inRowIndex][inColIndex];
++inRowIndex;

if (inRowIndex == ROWS)
{
inRowIndex = 0;
++inColIndex;
}

if (inColIndex < COLS)
{
return currentValue + Func(iarrnArr, inRowIndex, inColIndex);
}
else
{
return 0;
}
}

קפיש?

פורסם
  • מחבר

תודה רבה.

רק רציתי לציין שיש לך שגיאה קטנה - כאשר אנחנו מגיעים לסוף המטריצה (תנאי ה-else) אם תחזיר 0

אז התוצאה המוחזרת מהפונ' בסופו של דבר תהיה של כל המטריצה פחות התא האחרון,

ולכן יש להחזיר את nCurrentSum.

פורסם

צודק.

אגב, וריאציה אפשרית נוספת:

int Func(int iarrnArr[ROWS][COLS], int inRowIndex, int inColIndex)
{
if (inColIndex >= COLS)
return 0;

if (inRowIndex >= ROWS)
return Func(iarrnArr, 0, inColIndex + 1);

return iarrnArr[inRowIndex][inColIndex] + Func(iarrnArr, inRowIndex+1, inColIndex);
}

באופן זה, יש קצת יותר קריאות לפונקציה הרקורסיבית מהנחוץ, אבל הקוד יותר נקי ומסודר.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים