עבור לתוכן

בעיה בC# ברקורסיה, לא מקבל את הקוד (שגיאת ריצה)

Featured Replies

פורסם

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{

static int haluka(int a,int b)
{
if (a == 0)
return 1;
if (a < b)
return 0;
if (b <a)
{
a = a - b;
if (haluka(a, b)==1)
return 1;
else
return 0;
}


}
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int h = haluka(a, b);
Console.Write(h);
}
}
}

מישומה הוא מחליט שישנה שיגאת הרצה בקוד ולא מאפשר לי להריץ אותו,

הוא רושם לי שבמחלקה ישנה בעיה שלא כל הערכים מחזירים ערך

למרות שכולם כן.

מה יכולה להיות הבעיה?

פורסם

לא כל ה-return נמצא בתוך IF תעשה אחד מחוץ ל-IF

פורסם

בתור התחלה אין לך טיפול במצב ש-a ו-b שווים.

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

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

אתה יכול להוסיף return 1 אחרי כל ה-IF ואז הוא יקמפל, וגם יחזיר תשובה נכונה אם a==b.

פורסם

^^^ מחזק.

יש להוסיף לפחות ELSE אחד בסוף (אפילו אם הוא פיקטיבי [במקרה הזה הוא לא]).

פורסם
  • מחבר

או קי הופתי למצב של A וB שווים, יענו ככה

using System; 
namespace ConsoleApplication1
{
class Program
{

static int haluka(int a,int b)
{
if (a == 0)
return 1;
if (a < b)
return 0;
if (b <a)
{
a = a - b;
if (haluka(a, b)==1)
return 1;
else
return 0;
}
if(a==b)
retrun 1;
}
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int h = haluka(a, b);
Console.Write(h);
}
}
}

אבל זה עדיין לא עובד.

פורסם

כמו שאמרתי קודם:

...

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

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

...

אתה חייב שיהיה return מחוץ לכל ה-IF-ים.

פורסם

אגב הרקורסיה שלך לא כל כך איכותית מבחינת קריאות ותכנון

כל הרקורסיה צריכה להשען על העניין הבא

if(a<b) return 0;
else return hauka(a-b,b) +1;

כמובן יש צורך במיקרי קצה

פורסם
  • מחבר

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

ואגב זה עובד עכשיו

פורסם

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

ואגב זה עובד עכשיו

כלל לא דיברתי על יעילות, על אף שיש יעילות גם ברקורסיה

דיברתי על קריאות, על תכנון קוד, זה הרבה מעבר

ודרכים מוזרות הן לא בהכרח דרכים טובות, צריך לעבוד על זה

בכל אופן שיהיה בהצלחה

פורסם

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

ואגב זה עובד עכשיו

מאיפה בדיוק הבאת את השקר הזה?

פורסם

זה נכון. בהשוואה ללולאה רגילה, רקורסיה היא הרבה פחות יעילה (לכל קריאה לפונקציה יש overhead).

אם מדובר ברקורסיית זנב, אז יש שפות מסויימות שיודעות לייעל את זה (בעיקר שפות שבהן אין לולאות, ע"ע lisp).

פורסם

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

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

פורסם


static int haluka(int a,int b)
{
if (a == 0)
return 1;
if (a < b)
return 0;
if (b <a)
{
a = a - b;
if (haluka(a, b)==1)
return 1;
else
return 0;
}
if(a==b)
retrun 1;
}

זה מה שאתה כתבת אבל זה לא "נכון" ומסודר כך.

הרבה יותר נכון וברור רק "יציאה אחת" ולעדכן משתנה אחר שאותו תחזיר, למשל:


static int haluka(int a,int b)
{
int idxToReturn = -1;//ככה אפשר לדעת אם יש בעיה במהלך הריצה
if (a == 0)
idxToReturn = 1;
if (a < b)
idxToReturn = 0;
if (b <a)
{
a = a - b;
if (haluka(a, b)==1)
idxToReturn = 1;
else
idxToReturn = 0;
}
if(a==b)
idxToReturn = 1;
retrun idxToReturn;
}

פורסם

הרבה יותר נכון וברור רק "יציאה אחת" ולעדכן משתנה אחר שאותו תחזיר, למשל:

שטויות. אין סיבה שתהיה רק יציאה אחת מהפונקציה.

ארכיון

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

דיונים חדשים