רקורסיה.

the another one

New member
זה לא קשור.

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

the another one

New member
הנה אפילו דוגמה :

אצלי במחשב הגבול הוא 10380. מעבר לזה - רקורסיה רגילה תגרום ל stack overflow. ואל תשימו לב לתוצאות של !N עבור N = משהו מוגזם...

#include <iostream.h> long double RNormalFact(int N) { if (N==0) return 1; return N*RNormalFact(N-1); } long double RTailFact(int N,int M) { if (N==0) return M; M*=N; return RTailFact(N-1,M); } void main() { long double N; //proof : if N <= 10830 - both of the reqursiot work - there is an overflow but this isn't the issue. // if I change N to 10831 - only RTailFact will return a result. RNormalFact will cause stack overflow. N=10830; }​
 

annefan

New member
אהמ, ויני, התקדמנו קצת...

stack בעומק של 10 עד 15 קריאות? כברירת מחדל, בפונקצית עצרת מדובר על יותר מ-4500 קריאות ב-VC ויותר מ-35000 (!!) קריאות ב-gcc מעל cygwin. (התוצאה יוצאת מהטווח של long double הרבה לפני stack overflow)
 

vinney

Well-known member
טוב, קצת הגזמתי ../images/Emo13.gif

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

BanjoKazooie

New member
פי איזה הסבר מעולה

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

danielcs

New member
חישוב עצרת

Java: int fact(int n){ if (n==0) return 1; else System.out.println(n * fact(n-1)); }
 
משהו פה נראה קצת מוזר בדוגמה שלך

האם כל קריאה רקורסיבית אמורה להדפיס למסך?
 
מילא זה...../images/Emo26.gif

אבל העובדה שפרט לתנאי-העצירה אין return לא הפריעה לך??...
גם כן אלוהים
...
 

nirtheking

New member
../images/Emo26.gifנצל"ש

אני בונה פורום עץ מבנה ה-DB שלי הוא כזה: ID | ParentId | subject כאשר parentId מסמל אם ההודעה היא הודעה חדשה(=0) או תגובה להודעה מסוימת(=ID הודעה שמגיבים אליה) איך אני יכול להימנע מרקורסיה ולהשתמש בלולאות (הקוד הבסיסי מופיע כאן)
 

vinney

Well-known member
מה הבעיה?

for (id=ParentId;id!=0;) { DoWhateverYouWantToDoWithTheParent(id); ParentId = id.ParentId; }​
 

nirtheking

New member
תודה ../images/Emo13.gif

הצלחתי לסדר בעזרת SQL את התוצאות כך שיצאו לי באופן ליניארי במבנה נכון של המסד. עכשיו אין לי צורך ברקורסיה אלא פשוט בקצת DOM בסיסי
 

vinney

Well-known member
אז תגיד SQL ../images/Emo13.gif

PRIOR BY עושה את זה מצוין, אם אני זוכר נכון
 

nirtheking

New member
אני רציתי בהתחלה פתרון ב-JS

פשוט הצלחתי להיפתר מרקורסיה בדרך אחרת ע"י סידור הרשומות ב-SQL ואני לא מכיר משפט כזה: PRIOR BY ב-SQL (לפחות לא באקסס) אני מכיר ORDER BY שבו השתמשתי
 

vinney

Well-known member
זה מORACLE

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

nirtheking

New member
צודק

ואם העיבוד הוא לצורך תצוגה בלבד אז רצוי להעביר את העיבוד ללקוח ולא להשאיר את הפעולה לשרת (שיקולי משאבים ויעילות)
 

Nsof

New member
הדפסת עץ

אני מניח שכל עץ מכיל ערך כלשא שאותו נדפים וכן אוסף של תתי עצים.
PrintTree (Tree T) 1) Print T's value 2) For each SubTree 2A) PrintTree(SubTree)​
כל מבנה נתונים שהגדרתו רקוסיבית (כמו עץ) בד"כ יגרור שימוש רחב באלג' רקורסיבים לביצוע פעולות עליו. בנוסף יש הרבה בעיות שיותר טיבעי לפתור בצורה רקורסיבית לדוגמא
 
למעלה