++C רשימות - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

++C רשימות


נעמה.

Recommended Posts

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

זה מה שכתבתי עד עכשיו :

(הפונקציות Add, IsEmpty,RemoveFirst מוגדרות בקובץ header )

השאלה שלי: איך אני מחזירה את הרשימה ההפוכה לתכנית הראשית. (איך אפשר לעשות return temp)

קוד:

template <class T>

void Revers(List<T> list)

{

List<int>temp;//הצהרה על רשימת עזר

while(!list.IsEmpty())

{

temp.Add(list.RemoveFirst());

}

}

void main()

{

List<int>list;

int i=0;

while(i<9)//הצבת ערכים ברשימה

{

list.Add(i*2+5);

i++;

}

cout<<"list is: ";

list.print();//הדפסת הרשימה

Revers(list);//קריאה לפונקציה להפיכת הרשימה

cout<<"\n\nlist revers is: ";

list.print();//הדפסת הרשימה ההפוכה

getche();

}

קישור לתוכן
שתף באתרים אחרים

  • תגובות 35
  • נוצר
  • תגובה אחרונה

משתתפים בולטים בדיון

משתתפים בולטים בדיון

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

לגבי השאלה שלך - יש שתי דרכים לעשות מה שאת רוצה:

1. השינוי ייעשה in-place, כלומר הרשימה שאת נותנת היא זו שמשתנה (ככה בעצם התייחסת אליה ב-main). במקרה הזה, את צריכה אחרי ההיפוך להחזיר את כל האיברים מ-temp ל-list. שימי לב שזה יגרום להיפוך נוסף של האיברים, אז את חייבת בעצם להשתמש בעוד רשימה זמנית (כלומר תעתיקי מ-temp לרשימה temp2 ומשם חזרה ל-list).

2. השינוי לא יהיה in-place, כלומר הפונקציה תיצור רשימה חדשה ותחזיר אותה. במקרה זה, הפונקציה לא תחזיר void אלא List<int>, ובסופה תוכלי לעשות return temp. שימי לב שבמקרה הזה, הפונקציה למעשה הורסת את list (כי את מוחקת את כל האיברים שלו), אז תצטרכי לבנות אותו מחדש לפני שאת מחזירה את temp (דרך אפשרית היא ליצור במקביל שתי רשימות temp,temp2 שיכילו את הרשימה ההפוכה, ואז תחזירי את האיברים מ-temp2 ל-list).

UnsignedInteger - זה יפעל רק אם היא הגדירה Copy Constructor שמעתיק את כל הרשימה, ולא רק את המצביע. אחרת אין משמעות ל-byval/byref מהבחינה הזו.

קישור לתוכן
שתף באתרים אחרים

תודה על ההערה החשובה.

ישנה פונקציה של copy constructor- לא יודעת איך היא עוזרת לי.

לא הבנתי את הענין של המצביע. אם אני עושה שהפונקציה תחזיר לתכנית return temp גם לאחר הקריאה לפונקציה הפונקציה עושה מה שעושה, ואז בחזרה לתכנית הראשית, - רשימה temp ריקה ורשימה list מכילה את כל האיברים כאילו לא עשיתי כלום!!!!!!!!!!!

איך אני מחזירה את הרשימה temp המעודכנת??

קישור לתוכן
שתף באתרים אחרים

קודם כל' date=' הערה קטנה (אבל חשובה): כשאת כותבת קוד בפורום, אל תצמידי אותו לשמאל, אלא תשתמשי בכפתור "הכנס קוד" (הכפתור עם הציור של סולמית). ככה הקוד ייראה יותר טוב.

לגבי השאלה שלך - יש שתי דרכים לעשות מה שאת רוצה:

1. השינוי ייעשה in-place, כלומר הרשימה שאת נותנת היא זו שמשתנה (ככה בעצם התייחסת אליה ב-main). במקרה הזה, את צריכה אחרי ההיפוך להחזיר את כל האיברים מ-temp ל-list. שימי לב שזה יגרום להיפוך נוסף של האיברים, אז את חייבת בעצם להשתמש בעוד רשימה זמנית (כלומר תעתיקי מ-temp לרשימה temp2 ומשם חזרה ל-list).

2. השינוי לא יהיה in-place, כלומר הפונקציה תיצור רשימה חדשה ותחזיר אותה. במקרה זה, הפונקציה לא תחזיר void אלא List<int>, ובסופה תוכלי לעשות return temp. שימי לב שבמקרה הזה, הפונקציה למעשה הורסת את list (כי את מוחקת את כל האיברים שלו), אז תצטרכי לבנות אותו מחדש לפני שאת מחזירה את temp (דרך אפשרית היא ליצור במקביל שתי רשימות temp,temp2 שיכילו את הרשימה ההפוכה, ואז תחזירי את האיברים מ-temp2 ל-list).

[/quote']

UnsignedInteger - זה יפעל רק אם היא הגדירה Copy Constructor שמעתיק את כל הרשימה' date=' ולא רק את המצביע. אחרת אין משמעות ל-byval/byref מהבחינה הזו.

[/quote']

כנ"ל, רק ההפך ;D

איך הcopy ctor ממומשת?

קישור לתוכן
שתף באתרים אחרים

copy constructor ממומש כך:

 template <class T>
List<T>::List(const List<T> &list)
{
Link<T> *src,*trg;
if(list.first!=NULL)
{
first=new Link<T>((list.first)->value,NULL);
src=list.first;
trg=first;
while(src->next!=NULL)
{
trg->next=new Link<T>;
((scr->next)->value,NULL);
scr=scr->next;
trg=trg->next;
}
}
}

כאשר Link זוהי מחלקה לייצוג איבר בודד ברשימה.

מה זה UnsignedInteger ?

קישור לתוכן
שתף באתרים אחרים

אהההה, יש טעות בcopy constructor הנ"ל.

הינה בלי טעות- (כרגע, בהרכצת התכנית , רשימה temp ריקה כשאני מבקשת להדפיס אותה.)

template <class T>
List<T>::List(const List<T> &list)
{
Link<T> *src,*trg;
if(list.first!=NULL)
{
first=new Link<T>((list.first)->value,NULL);
src=list.first;
trg=first;
while(src->next!=NULL)
{
trg->next=new Link<T>
((src->next)->value,NULL);
src=src->next;
trg=trg->next;
}
}
}

קישור לתוכן
שתף באתרים אחרים

אידיאלית עדיף שתקבלי שני פרמטרים - המחסנית המקורית SRC ומחסנית ריקה DST, שתיהם by reference כמו ש-UnsignedInteger הציע.

הפונקציה תרוקן את המחסנית SRC לתוך DST.

הנה פסאודו קוד:



bool ReverseStack( List<T>& src, List<T>& dst )
{
if ( &src == &dst ) return false; // error
if ( !dst.IsEmpty() ) return false; // probably error

while( !src.IsEmpty ) {
if ( !dst.Add( src.RemoveFirst() ) ) return false; // error
}

return true; // success, life is good, got eat icecream
}

קישור לתוכן
שתף באתרים אחרים

האם זכרת להצהיר על הפרמטרים כ-reference (כלומר עם &)?

bool ReverseStack( List<T>& src, List<T>& dst ) // parameters are passed by reference

לעומת

bool ReverseStack( List<T> src, List<T> dst ) // parameters are passed by value

קישור לתוכן
שתף באתרים אחרים

כן , בוודאי.

רק שכשהעתקי את הקוד שZelig הציע, הקומפיילר הראה טעות על התנאי if , אז במקום לרשום אותו ככה:

 while( !list.IsEmpty ) {
if ( !temp.Add( list.RemoveFirst() ) ) return false; // error
}

רשמתי ככה:

 while( !list.IsEmpty()==0) 
{
temp.Add(list.RemoveFirst());
if(!temp.FirstElm()) return false; // error

}

זה בעיה?

קישור לתוכן
שתף באתרים אחרים

ארכיון

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


×
  • צור חדש...