średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

flowers_evil
Użytkownik
Użytkownik
Posty: 87
Rejestracja: 8 mar 2009, o 09:27
Płeć: Kobieta
Podziękował: 41 razy

średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

Post autor: flowers_evil »

Witam mam taki program ale nie bardzo rozumiem jak on działa i proszę o wytłumaczenie kodu :

Kod: Zaznacz cały



Struct element
{ int x; 
element *next 
element *prev;}

Float srednia (element *ptr)
{ int l=0; 
   Float sm=0;
    Element *tmp=ptr;

While(tmp!=0) //1 warunek 
{l=l+1              //to rozumiem tutaj po prostu liczmy ilosc elementow zeby potem przez nia podzielisc srednia 
Sr=sr+tmp->x;   // co dzieje się w tej linijce ?
Tmp=tmp->next;} // tutaj po prostu przemieszczamy się dalej 

Tmp=ptr->prev; // nie wiem po co jest ta linijka? 

While(tmp!=0)//2 warunek jest taki sam, czemu ? czy wtedy wykonają się obydwie pętle while?
{ l=l+1;          
Sr=sr+tmp ->x; // tutaj również nie wiem co dzieje się w tej linicje 
Tmp=tmp->prev;//tutaj przemiszczay się w lewą stronę od wskaźnika ptr=tmp
}

Return (sr/l)

Proszę o wytłumaczenie co się tutaj dzieje.. są dwie pętle while z tym samym warunkiem więc która pętla zostaje wykonana? a jeśli oby dwie to mamy dwa l ??
Awatar użytkownika
Konikov
Użytkownik
Użytkownik
Posty: 497
Rejestracja: 13 mar 2008, o 18:56
Płeć: Mężczyzna
Lokalizacja: z całki tego świata
Podziękował: 66 razy
Pomógł: 44 razy

średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

Post autor: Konikov »

Kod: Zaznacz cały

Sr=sr+tmp->x;   // co dzieje się w tej linijce ?
Chyba powinno być tak:

Kod: Zaznacz cały

sr = sr + tmp->x;   // co dzieje się w tej linijce ?
prawda? Po prostu do średniej (tak naprawdę to nie jest średnia, ale suma kolejnych elementów...) dodajemy wartość, jaka jest przechowywana w elemencie, na który obecnie wskazuje x. Poczytaj czym są wskaźniki i jak ich się używa.

Z kolei ja czegoś nie rozumiem w tym kodzie. Zakładamy, że to jest lista cykliczna, tak? W takim razie ona zawsze ma następny i poprzedni element, a Twoja procedura się nie zakończy (poza tym w pierwszym while liczysz po kolei, a w drugim wspak, więc jeśli to byłaby niecykliczna lista, to wszystko pomiędzy elementem wskazywanym przez "ptr" a końcem policzone byłoby dwukrotnie). Ja bym raz przeleciał po wszystkich elementach wychodząc z pętli gdy znów wskazujemy na to samo co ptr, czyli zrobił tak:

Kod: Zaznacz cały

float srednia(element *ptr)
{
   int liczbaElementow = 0;
   float suma = 0;
   element *tmp = ptr;

   if(ptr == 0) // Jeśli nie ma żadnego elementu - zwróć zero.
      return 0;

   do // ponieważ na początku tmp == ptr, to musimy choć raz policzyć ten element
   {
      ++liczbaElementow; // zwiększamy liczbę dotychczas policzonych elementów
      suma = suma + tmp->x; // do sumy dodajemy wartość obecnie wskazywanego
      tmp = tmp->next; // przechodzimy do następnego elementu
   } while(tmp != ptr); // warunek przechodzenia dalej

   return (suma / liczbaElementow);
}
Kontroluj małe i duże litery w zmiennych (zmienna "Sr" to co innego niż "sr"!) i w typach, a także średniki. Poza tym używaj śmiało double zamiast float, bo float jest dość ograniczonej precyzji, a pamięci w kompie raczej nam tak szybko nie zabraknie ;]
flowers_evil
Użytkownik
Użytkownik
Posty: 87
Rejestracja: 8 mar 2009, o 09:27
Płeć: Kobieta
Podziękował: 41 razy

średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

Post autor: flowers_evil »

ok Twoją wersje programu lepiej rozumiem
Tylko po prostu taką wersje miałam podaną na wykładach więc stwierdziłam, że jest dobrze tylko nie do końca rozumiałam ją.


Czyli pierwszy warunek (linijka 10) brzmi: do kiedy tmp=ptr..
hymm.. ale on będzie tylko raz spełniony bo potem się przesuwamy dalej (linijka 14) i wtedy tmp juz nie wynosi ptr tylko jest koljnym elementem następnym po ptr.?


hym a nie można zrobić tak :

Kod: Zaznacz cały



float srednia(element *ptr)
{
   int liczbaElementow = 0;
   float suma = 0;
   element *tmp = ptr;

   if(ptr == 0) 
      return 0;

   tmp=tmp->next ; //przechodzimy o jeden element dalej aby warunek while niżej się spełnił?
   
  while(tmp != ptr);
{
      ++liczbaElementow; 
      suma = suma + tmp->x; 
      tmp = tmp->next; 
   }  

   return (suma / liczbaElementow);
}
Awatar użytkownika
Konikov
Użytkownik
Użytkownik
Posty: 497
Rejestracja: 13 mar 2008, o 18:56
Płeć: Mężczyzna
Lokalizacja: z całki tego świata
Podziękował: 66 razy
Pomógł: 44 razy

średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

Post autor: Konikov »

Nie ;] Znów radzę zasymulować na kartce ;] Teraz chcesz zrobić tak, że zaczynasz zliczanie od następnego elementu po ptr. Jednakże gdy przejdziesz do elementu ptr:

Kod: Zaznacz cały

tmp = tmp->next;
to wyjdziesz z pętli nie licząc tego elementu ;] Jeśli chcesz tak zapisać, to musisz zrobić to, co jest w pętli przed nią:

Kod: Zaznacz cały

float srednia(element *ptr)
{
   int liczbaElementow = 0;
   float suma = 0;
   element *tmp = ptr;

   if(ptr == 0) // Jeśli nie ma żadnego elementu - zwróć zero.
      return 0;

   ++liczbaElementow; // zwiększamy liczbę
dotychczas policzonych elementów
   suma = suma + tmp->x; // do sumy dodajemy wartość obecnie wskazywanego
   tmp = tmp->next; // przechodzimy do następnego elementu

   while(tmp != ptr)
   {
      ++liczbaElementow; // zwiększamy liczbę
dotychczas policzonych elementów
      suma = suma + tmp->x; // do sumy dodajemy wartość obecnie wskazywanego
      tmp = tmp->next; // przechodzimy do następnego elementu
   }

   return (suma / liczbaElementow);
}
(a to samo robi do-while).

Tamten kod byłby niezły dla acyklicznej listy, dwie pętle są po to, że nasz element może być któryś w liście. Więc na początku zliczamy wszystkie elementy wprzód elementu wskazywanego przez ptr (oraz on sam), a:

Kod: Zaznacz cały

tmp=ptr->prev; // nie wiem po co jest ta linijka?
oraz druga pętla robi, że liczymy w tył od poprzedniego elementu do ptr. Musiałaś pominąć info, że to kod dla acyklicznej listy (listy bez cykli) ;]

Pozdrowienia i good luck
K.
Ostatnio zmieniony 27 wrz 2010, o 18:14 przez Konikov, łącznie zmieniany 1 raz.
flowers_evil
Użytkownik
Użytkownik
Posty: 87
Rejestracja: 8 mar 2009, o 09:27
Płeć: Kobieta
Podziękował: 41 razy

średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

Post autor: flowers_evil »

Ok rozumiem dziękuje bardzo
Awatar użytkownika
Konikov
Użytkownik
Użytkownik
Posty: 497
Rejestracja: 13 mar 2008, o 18:56
Płeć: Mężczyzna
Lokalizacja: z całki tego świata
Podziękował: 66 razy
Pomógł: 44 razy

średnia elementów listy cyklicznej 2 kier. wytlumaczenie kod

Post autor: Konikov »

Nie ma sprawy ;]
ODPOWIEDZ