בבקשה
#include <stdio.h>
void Partition(int n, int limit, int value[29], int remember);
void main(){
int n=0,i=0;
int limit, value[30];
for (i=0; i<30; i++)
value = 0;
scanf("%d",&limit);
Partition(limit,limit,value, 0);
}
void Partition(int n, int limit, int value[30], int remember)
{
int i, k=1, min;
if (n < limit)
min = n;
else
min = limit;
if (n>0)
{
for (i=min; i>0; i--)
{
for (k=0; k<30; k++)
{
if (value[k] == 0)
{
value[k] = i;
break;
}
}
Partition(n-i, i, value, remember+1);
for (k=remember; k<30; k++)
value[k] = 0;
}
}
else
{
for (i=0; i<30; i++)
if (value != 0)
printf("%2d", value);
printf("\n");
}
}
הבעיה אצלך, כמו שהתחלת לציין קודם, הייתה באיפוס המערך value שהתבצע תמיד עבור על הערכים. למעשה האיפוס אמור להיות רק עבור הערכים שאנחנו רוצים למצוא עבורם חלופה אחרת. למשל, אם אנחנו מחפשים partition של 5, והחלטנו להתחיל ב-3, אז האפשרות הראשונה שנבדקת היא להוסיף לו 2. אחר כך צריך לבדוק אפשרות להוסיף לו 1 ו-1.
כלומר אפשרות ראשונה:
3, 2
והאפשרות השניה:
3, 1, 1
במעבר בין שתי האפשרויות לא צריך לאפס את כל המערך אלא רק את המקום בו היה 2 - כך שנפנה מקום ל-1 הראשון, ונמשיך משם. תעבור טוב על הקוד שלך ותראה שהוא איפס את כל המערך.
אני הוספתי פרמטר לרקורסיה שאומר כמה איברים צריך לזכור, כלומר צריך לאפס רק את האיברים שגדולים מפרמטר זה. שים לב שככל שנכנסים לעומק הרקורסיה, ערכו של פרמטר זה גדל, כלומר צריך להתחיל לאפס רק באיברים המתקדמים יותר.
גם שיניתי את המקום בקוד בו מתבצע האיפוס - זה קורה כעת בסוף השלב הרקורסיבי, רגע לפני החזרה לשלב הקודם.
דרך אגב, הייתה לך גם בעיית זמן ריצה שנבעה מזה שהגדרת מערך בגודל 29 וניגשת לאיבר ה-29 בו. אפשר לפתור את זה בקלות על ידי הגדרת מערך בגודל 30.
בברכה,
מתן,
[URL='http://www.mlcollege.co.il']www.mlcollege.co.il[/URL]
#include <stdio.h>
void Partition(int n, int limit, int value[29], int remember);
void main(){
int n=0,i=0;
int limit, value[30];
for (i=0; i<30; i++)
value = 0;
scanf("%d",&limit);
Partition(limit,limit,value, 0);
}
void Partition(int n, int limit, int value[30], int remember)
{
int i, k=1, min;
if (n < limit)
min = n;
else
min = limit;
if (n>0)
{
for (i=min; i>0; i--)
{
for (k=0; k<30; k++)
{
if (value[k] == 0)
{
value[k] = i;
break;
}
}
Partition(n-i, i, value, remember+1);
for (k=remember; k<30; k++)
value[k] = 0;
}
}
else
{
for (i=0; i<30; i++)
if (value != 0)
printf("%2d", value);
printf("\n");
}
}
הבעיה אצלך, כמו שהתחלת לציין קודם, הייתה באיפוס המערך value שהתבצע תמיד עבור על הערכים. למעשה האיפוס אמור להיות רק עבור הערכים שאנחנו רוצים למצוא עבורם חלופה אחרת. למשל, אם אנחנו מחפשים partition של 5, והחלטנו להתחיל ב-3, אז האפשרות הראשונה שנבדקת היא להוסיף לו 2. אחר כך צריך לבדוק אפשרות להוסיף לו 1 ו-1.
כלומר אפשרות ראשונה:
3, 2
והאפשרות השניה:
3, 1, 1
במעבר בין שתי האפשרויות לא צריך לאפס את כל המערך אלא רק את המקום בו היה 2 - כך שנפנה מקום ל-1 הראשון, ונמשיך משם. תעבור טוב על הקוד שלך ותראה שהוא איפס את כל המערך.
אני הוספתי פרמטר לרקורסיה שאומר כמה איברים צריך לזכור, כלומר צריך לאפס רק את האיברים שגדולים מפרמטר זה. שים לב שככל שנכנסים לעומק הרקורסיה, ערכו של פרמטר זה גדל, כלומר צריך להתחיל לאפס רק באיברים המתקדמים יותר.
גם שיניתי את המקום בקוד בו מתבצע האיפוס - זה קורה כעת בסוף השלב הרקורסיבי, רגע לפני החזרה לשלב הקודם.
דרך אגב, הייתה לך גם בעיית זמן ריצה שנבעה מזה שהגדרת מערך בגודל 29 וניגשת לאיבר ה-29 בו. אפשר לפתור את זה בקלות על ידי הגדרת מערך בגודל 30.
בברכה,
מתן,
[URL='http://www.mlcollege.co.il']www.mlcollege.co.il[/URL]