עבור לתוכן

++C רשימות

Featured Replies

פורסם

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

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

(הפונקציות 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
  • צפיות 3.7k
  • נוצר
  • תגובה אחרונה

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

פורסם

תשלחי את הרשימה BY REF.

ד.א. למה לא לעשות FRIENDלמחלקה LIST?

פורסם
  • מחבר

מה זה ואיך עושים את זה???

רשמת לי דברים בסינית.

אשמח להסבר.

תודה על התגובה. :s07:

פורסם

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

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

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

פורסם

מה זה UnsignedInteger ?

לא משנה טעיתי..

פורסם
  • מחבר

כמובן ששלחתי את האיברים עם הסימן & .

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

UnsignedInteger, מצטערת.

זה היה נראה כמו מילת קוד שתפעל רק אם אעשה copy constructor.

פורסם

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

פורסם
  • מחבר

כן , בוודאי.

רק שכשהעתקי את הקוד ש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

}

זה בעיה?

ארכיון

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

דיונים חדשים