עבור לתוכן

לא הולך לי תרגיל ברקורסיה פשוטה שפת C#

Featured Replies

פורסם

שלום לכולם. אני מנסה לעשות תרגיל ואני כבר משתגע :facepalm: לא הולך לי...

צריך לכתוב פעולה רקורסיבית המקבלת מספר INT ומחזירה את ממוצע ספרותיו.

זה מה שרשמתי:

  class sum
{
public static int Give(int n)
{

return MakeSum(n,0,0);
}
public static int MakeSum(int n,int i,int sum)
{
if (n == 0)
return (sum/i);
else
i++;
return (sum=sum+((n % 10) + MakeSum((n / 10),i,sum)));
}
}
}

מה הבעיה פה? זה פשוט מחזיר לי רק את החיבור של המספר. למשל למספר 453

4+5+3=12 אבל אני לא מבין למה הוא לא מחלק לי ב-i....

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

תודה רבה לעוזרים :yelclap:

פורסם

תבדוק מה קורה עם המשתנה sum, הרקורסיה שלך תמיד מעבירה אותו עם הערך 0, בעיקרון יש עוד בעיה אבל תתחיל בזה.

פורסם

מה בדיוק ניסית לעשות בשורה האחרונה שם? למה יש לך = בשורה של ה-return? זה ממש מבלבל ולא ברור. אתה צריך להחזיר את תוצאת הקריאה ל-MakeSum, ולא להוסיף לה דברים.

פורסם
  • מחבר

לא הבנתי אותכם כל כך... האמת שכשאני עובר על הרקורסיה בראש זה נראה לי נכון...

תראו לעשות את החיבור של כל מספרים אני מצליח. הבעיה שאני לא מצליח לעשות את מספר הפעמים השפעולה נעשת. לדוגמא אני מצליח לעשות למספר 453 . 4+5+3 הבעיה שעכשיו צריך לחלק את זה ב3.

אם אני מגדיר משתנה I וכל פעם עושה לו ++ , אז כשהוא חוזר על הרקורסיה הוא שוב יגדיר אותו ואז הוא יתאפס. מה אפשר לעשות ?

עריכה:

ניסתי לעשות שוב מחדש בצורה אחרת וזה בכל זאת לא עובד טוב.

זה מה שעשיתי:

  class average
{
public static int avg(int n, int k)
{
if (n == 0)
return (0);
else
{
k++;
return (((n % 10) + avg(n / 10,k))/k);
}
}

ובMAIN הגדרתי לו K=0 ואת N הוא קולט .

למשל הכנסתי 453 הוא מחזיר לי 6 :sleep:

פורסם

הפתרון הראשון שלך דווקא טוב בעיקרון, אבל כמו שאמרתי - מה שעשית ב-return היה מסורבל ולא ברור. תחשוב איך לפשט אותו.

פורסם

הבעיה שלך היא שהמכנה שלך משתנה עם הזמן.

הספרה הכי קטנה מתחלקת ב 1, זו שאחרי ב 2, וכן הלאה.

אם תגדיר את k בתוך המתודה, כמשתנה של המתודה (למעשה- static int), או שתעביר את k ע"י ייחוס (By reference), זה יפתור לך את הבעיה- משום שהמכנה יגיע לשיא הגודל שלו, ורק אז תתבצע החלוקה.

למעשה, הקוד שלך צריך להראות כך:

(מימוש ע"י Static Member


class average
{
public static int avg(int n)
{
static int k = 0;
if (n == 0)
return (0);
else
{
k++;
return (((n % 10) + avg(n / 10))/k);
}
}

מקווה שעזרתי!

שבוע טוב!

פורסם

רק שזה לא יעבוד - תנסה את הקלט 11 ותראה מה קורה.

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

פורסם

תשים לב שכאשר 0 == n אז זהו התנאי עצירה שלך

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

אתה צריך דווקא בסוף התהליך לחלק ב i, אחרי שאתה יודע את הסכום.

תנסה לעבוד עם הדייבגר ולאט לאט להבין, שלב אחר שלב. - או בעזרת טבלת אמת.

הפתרון שלי:

class Program

{

static void Main(string[] args)

{

int num = 0;

double avg = NumAvg(num);

avg.ToString();

}

public static double NumAvg(int n)

{

int sum = MakeSum(n, 0);

double avg = (double)sum / (double)n.ToString().Length;

return avg;

}

public static int MakeSum(int n, int sum)

{

if (n == 0) {

return (n);

}

else {

return (sum = sum + ((n % 10) + MakeSum((n / 10), sum)));

}

}

}

פורסם

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

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

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

פורסם
  • מחבר

נווו אז מה צריך לתקן??? תן רמז משהו.... הרגת אותנו כברר!!!

ניסתי לעשות משהו שחשבתי שהוא יותר חכם ואמור לעבוד

{
class avreage
{
public static int GetAvg(int num)
{
return (GetFinall(num) / AccDigts(num));
}
private static int AccDigts(int num)
{
if (num < 0)
return 1;
return (1+AccDigts (num/10));
}
private static int GetFinall(int num)
{
if (num < 0)
return num;
return (num % 10 + GetFinall(num / 10));
}
}
}

אין לי שום ארור בתוכנה עצמה

אבל כשאני מריץ אותו הוא נותן לי ארור כיאלו של "SEND" "DONT SEND"

למה זה לא עובד? זה ניראה לי גאוני ופתרון כל כך יעיל... (מרוב יואש מהשאלה הזו אני מתחיל לרשום כמו פאקצה\יליד FXP חחח )

פורסם

זה לא עובד כי AccDigts נכנס לרקורסיה אינסופית (למה שאי פעם num יהיה קטן מ-0?)

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

א. אל תעשה השמה (=sum) ו-return באותה השורה, זה מבלבל.

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

פורסם
  • מחבר

שינתי ב-AccDigts ל-num<10 וזה לא פתר את הבעיה.

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

בשורה הזו

        return (sum/i);

איך אני יכול לחלק את כל הסכום שיצא בI?

פורסם

מה זאת אומרת? בשורה הזו אין שום בעיה.

תרשום פה את הקוד אחרי שתיקנת אותו.

פורסם
  • מחבר

  class sum
{
public static int Give(int n)
{

return MakeSum(n,0,0);
}
public static int MakeSum(int n,int i,int sum)
{
if (n == 0)
return (sum/i);
else
i++;
return (((n % 10) + MakeSum((n / 10),i,sum)));
}
}
}

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

פורסם

שים לב לשני דברים:

א. אתה לא משנה את sum מאיטרציה לאיטרציה - הוא תמיד 0.

ב. אתה מוסיף את הערך של ספרת האחדות לתוצאה של MakeSum (שהיא ממוצע, ולא סכום). שוב אתה מערבב תוצאות משתי "משפחות" שונות.

חוץ מזה, שים לב שרק השורה ++i יושבת בתוך ה-else. אתה צריך להשתמש בסוגריים מסולסלים (במקרה הספציפי הזה התוצאה היא זהה, אבל זו עדיין טעות).

ארכיון

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

דיונים חדשים