Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Pascal - Ordinamento di una lista di interi tutti diversi tra loro in senso crescente
Forum - Pascal - Ordinamento di una lista di interi tutti diversi tra loro in senso crescente

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
fabioser (Normal User)
Rookie


Messaggi: 59
Iscritto: 12/05/2012

Segnala al moderatore
Postato alle 12:53
Lunedì, 30/07/2012
Salve a tutti, utenti e moderatori del Forum. Chiedo aiuto nella soluzione di un semplice problema. Si tratta di stampare in uscita una lista di interi ordinata in senso crescente, a partire da una lista data in ingresso, costituita da numeri interi tutti diversi tra loro. La soluzione che ho elaborato, per quel che riguarda la procedura di calcolo della lista ordinata di cui sopra, fa uso di due cicli while, l'uno annidato nell'altro, con il più interno che confronta via, via, i singoli elementi della lista con gli n,n-1,...,1 elementi successivi, per determinare i massimi che verranno inseriti in testa alla lista ordinata dal più grande al più piccolo.Tuttavia tale soluzione, quando vado ad eseguire il programma risolutivo da me elaborato, mi dà errore 216. Credo che ciò sia dovuto al fatto che nel ciclo più interno di questa procedura il ciclo while tenta l'accesso a valori di p=nil. Qualcuno tra voi è in grado di indicarmi la soluzione esatta, e segnalarmi eventuali errori? Riporto di seguito il codice del programma che ho compilato:

Codice sorgente - presumibilmente Delphi

  1. program ListaOrdinataInSensoCrescente(input,output);
  2. const bell=07;
  3. type punt=^elem;
  4.      elem= record
  5.                  val  : integer;
  6.                  next : punt;
  7.            end;
  8. var p,lista : punt;
  9.     n,max,risposta : integer;
  10.  
  11. procedure LeggiLista( var p : punt; k : integer);
  12. begin
  13.      if k=0
  14.      then p:=nil
  15.      else begin
  16.                new(p);
  17.                read(p^.val);
  18.                LeggiLista(p^.next,k-1);
  19.           end;
  20. end;{fine procedura LeggiLista}
  21. procedure OrdinamentoLista( var p,lista : punt);
  22. begin
  23.      {creo la lista degli elementi ordinati}
  24.      new(lista);
  25.      {il primo elemento di tale lista lo pongo uguale al primo della lista p
  26.      ed eventualmente se non è il più grande di p lo aggiornerò}
  27.      lista^.val:=p^.val;
  28.      while p<>nil
  29.      do begin
  30.              {inizializzazione del valore del massimo della lista in ingresso}
  31.              p^.val:=max;
  32.              p:=p^.next;
  33.              {confronto via via degli elementi di p con tutti i loro successivi
  34.              e aggiornamento della variabile max}
  35.              while p<>nil
  36.              do begin
  37.                      if p^.val>max
  38.                      then max:=p^.val;
  39.                      p:=p^.next;
  40.                 end;
  41.              {inserimento dell'elemento max ( che è il più grande via via tra gli n,n-1,..,1
  42.              elementi di p ) in testa alla lista ordinata così in senso crescente}
  43.              lista^.val:=max;
  44.              {aggionamento dell'elemento lista}
  45.              lista:=lista^.next;
  46.              {aggiornamento di p}
  47.              p:=p^.next;
  48.         end;
  49. end;{fine procedura OrdinamentoLista}
  50. {corpo del programma}
  51. begin
  52.      repeat
  53.            writeln('--------------------------- Dati di ingresso --------------------------------');
  54.            writeln;
  55.            writeln;
  56.            write('Fornire la dimensione della lista: ');
  57.            readln(n);
  58.            if n>20
  59.            then begin
  60.                      writeln(chr(bell),'Errore nei dati di ingresso! - STOP -');
  61.                      exit;
  62.                 end
  63.            else begin
  64.                      writeln;
  65.                      writeln;
  66.                      writeln('Fornire la lista in ingresso:');
  67.                      writeln;
  68.                      writeln;
  69.                      LeggiLista(p,n);
  70.                      writeln;
  71.                      writeln;
  72.                      OrdinamentoLista(p,lista);
  73.                      writeln;
  74.                      writeln;
  75.                      while(lista<>nil)
  76.                      do begin
  77.                              write(lista^.val:3,' ');
  78.                              lista:=lista^.next;
  79.                         end;
  80.                 end;
  81.                 writeln;
  82.                 writeln('Finito?');
  83.                 writeln;
  84.                 writeln;
  85.                 writeln('Scrivere 1 per terminare 2 per continuare');
  86.                 writeln;
  87.                 writeln;
  88.                 readln(risposta);
  89.      until(risposta=1);
  90.      readln;
  91.  
  92. end.



Ringraziando da ora chiunque saprà fornirmi la soluzione corretta vi saluto tutti. Ciao!!!:)

PM Quote
Avatar
gigisoft (Member)
Guru


Messaggi: 696
Iscritto: 11/10/2008

Segnala al moderatore
Postato alle 17:27
Lunedì, 30/07/2012
Ciao, c'e' un errore nella procedura LeggiLista in quanto di volta in volta il p^.Next non viene realmente aggiornato; potresti modificarla così:

Codice sorgente - presumibilmente Delphi

  1. Function LeggiLista(k : integer): punt;
  2. var p : punt
  3. begin
  4.      if k=0
  5.      then p:=nil
  6.      else begin
  7.                new(p);
  8.                read(p^.val);
  9.                p^.Next := LeggiLista(k-1);
  10.           end;
  11.  
  12.      LeggiLista := p;
  13.  
  14. end;{fine procedura LeggiLista}



e ovviamente nel programma principale la chiamerai cosi':

Codice sorgente - presumibilmente Plain Text

  1. p := LeggiLista(n);



Ciao. :k:

PM Quote
Avatar
fabioser (Normal User)
Rookie


Messaggi: 59
Iscritto: 12/05/2012

Segnala al moderatore
Postato alle 17:52
Lunedì, 30/07/2012
Ti ringrazio per il suggerimento. Ma io vorrei sapere se qualcuno di voi è in grado di segnalarmi l'errore nella procedura OrdinamentoLista. Forse va introdotta una variabile ausiliaria in modo da non incorrere nella chiamata di p=nil nel ciclo while più interno? E se sì, potresti formulare la risposta corretta in codice? Te ne sarei infinitamente grato...

PM Quote
Avatar
gigisoft (Member)
Guru


Messaggi: 696
Iscritto: 11/10/2008

Segnala al moderatore
Postato alle 18:15
Lunedì, 30/07/2012
intanto correggi la funzione LeggiLista come ti ho detto, perche' con quella che hai fatto tu ti ritrovi i valori dei p^.Next tutti sballati, e questo ti impedisce il corretto funzionamento della lista

Inoltre vedo ora che nella procedura di ordinamento fai per tutti e due i cicli innestati il controllo sulla stessa variabile (p), e gia' questa e' una cosa da non fare mai, poi noto che il metodo che usi per 'ordinamento e' totalmente sbagliato, non so che metodo avevi intenzione di implementare, ma sicuramente il codice che hai usato non funziona per niente, ti consiglio di riguardarti un po' di algoritmi di ordinamento.

Ciao. :k:

PM Quote
Avatar
fabioser (Normal User)
Rookie


Messaggi: 59
Iscritto: 12/05/2012

Segnala al moderatore
Postato alle 18:28
Lunedì, 30/07/2012
Credo che l'errore sia nel punto seguente
Codice sorgente - presumibilmente Delphi

  1. while p<>nil
  2.              do begin
  3.                      if p^.val>max
  4.                      then max:=p^.val;
  5.                      p:=p^.next;
  6.                 end;



poichè una volta individuato il valore di max per i vari n,n-1,..,1 elementi,questo vada via via estratto dalla lista di partenza p e posto in testa a lista e per questo credo sia necessario introdurre una variabile puntatore ausiliaria...

PM Quote
Avatar
fabioser (Normal User)
Rookie


Messaggi: 59
Iscritto: 12/05/2012

Segnala al moderatore
Postato alle 18:47
Lunedì, 30/07/2012
O.K., hai perfettamente ragione. Non mi ero reso conto della gravità dell'errore; cercherò di seguire i tuoi consigli e riscrivere completamente la procedura OrdinamentoLista...Grazie comunque!!!

PM Quote
Avatar
fabioser (Normal User)
Rookie


Messaggi: 59
Iscritto: 12/05/2012

Segnala al moderatore
Postato alle 11:43
Martedì, 31/07/2012
Ho provato a riscrivere la procedura OrdinamentoLista. Tuttavia incontro due difficoltà : a) L'estrazione dei vari massimi via via decrescenti, dalla lista p ed il loro inserimento nella variabile 'lista'.
b) l'uso di un'altra variabile q per rappresentare la lista data in ingresso,nel ciclo while più interno.
Il codice del programma, che tuttavia così com'è non funziona, tenuto conto anche dei suggerimenti proposti è il seguente:

Codice sorgente - presumibilmente Delphi

  1. program ListaCrescente(input,output);
  2.     const bell=07;
  3.     type punt=^elem;
  4.          elem= record
  5.                      val  : integer;
  6.                      next : punt;
  7.                end;
  8.     var p,lista : punt;
  9.         n,max,risposta : integer;
  10.  
  11.     Function LeggiLista(k : integer): punt;
  12.     var p : punt ;
  13.     begin
  14.          if k=0
  15.          then p:=nil
  16.          else begin
  17.                    new(p);
  18.                    read(p^.val);
  19.                    p^.Next := LeggiLista(k-1);
  20.               end;
  21.      
  22.          LeggiLista := p;
  23.      
  24.     end;{fine function LeggiLista}
  25.     procedure OrdinamentoLista( var p,lista : punt);
  26.     var q : punt;
  27.     begin
  28.          {creo la lista degli elementi ordinati}
  29.          new(lista);
  30.          {il primo elemento di tale lista lo pongo uguale al primo della lista p
  31.          ed eventualmente se non è il più grande di p lo aggiornerò}
  32.          lista^.val:=p^.val;
  33.          while p<>nil
  34.          do begin
  35.                  {inizializzazione del valore del massimo della lista in ingresso}
  36.                  p^.val:=max;
  37.                  p:=p^.next;
  38.                  q:=p;
  39.                  {confronto via via degli elementi di p con tutti i loro successivi
  40.                  e aggiornamento della variabile max}
  41.                  while q<>nil
  42.                  do begin
  43.                          if q^.val>max
  44.                          then max:=q^.val;
  45.                          q:=q^.next;
  46.                     end;
  47.                  {inserimento dell'elemento max ( che è il più grande via via tra gli n,n-1,..,1
  48.                  elementi di p ) in testa alla lista ordinata così in senso crescente}
  49.                  lista^.val:=max;
  50.                  {aggionamento dell'elemento lista}
  51.                  lista:=lista^.next;
  52.                  {aggiornamento di p}
  53.                  p:=p^.next;
  54.             end;
  55.     end;{fine procedura OrdinamentoLista}
  56.     {corpo del programma}
  57.     begin
  58.          repeat
  59.                writeln('--------------------------- Dati di ingresso --------------------------------');
  60.                writeln;
  61.                writeln;
  62.                write('Fornire la dimensione della lista: ');
  63.                readln(n);
  64.                if n>20
  65.                then begin
  66.                          writeln(chr(bell),'Errore nei dati di ingresso! - STOP -');
  67.                          exit;
  68.                     end
  69.                else begin
  70.                          writeln;
  71.                          writeln;
  72.                          writeln('Fornire la lista in ingresso:');
  73.                          writeln;
  74.                          writeln;
  75.                          p:=LeggiLista(n);
  76.                          writeln;
  77.                          writeln;
  78.                          OrdinamentoLista(p,lista);
  79.                          writeln;
  80.                          writeln;
  81.                          while(lista<>nil)
  82.                          do begin
  83.                                  write(lista^.val:3,' ');
  84.                                  lista:=lista^.next;
  85.                             end;
  86.                     end;
  87.                     writeln;
  88.                     writeln('Finito?');
  89.                     writeln;
  90.                     writeln;
  91.                     writeln('Scrivere 1 per terminare 2 per continuare');
  92.                     writeln;
  93.                     writeln;
  94.                     readln(risposta);
  95.          until(risposta=1);
  96.          readln;
  97.      
  98.     end.



Sarò grato da ora a chiunque sia in grado di fornirmi la versione corretta della procedura OrdinamentoLista. Ciao a tutti!!!:)

PM Quote
Avatar
gigisoft (Member)
Guru


Messaggi: 696
Iscritto: 11/10/2008

Segnala al moderatore
Postato alle 11:42
Mercoledì, 01/08/2012
Allora, un piccolo chiarimento,

tu che vuoi fare?
Ordinare la lista che hai?
Oppure creare una copia ordinata della lista, lasciando l'originale inalterata (e quindi disordinata)?

perche' nel primo caso, non ha senso che nella OrdinamentoLista tu ne crei un'altra;

nel secondo caso invece l'approccio che usi e' sbagliato, per esempio, su quali basi come prima istruzione fai questa assegnazione?

Codice sorgente - presumibilmente Plain Text

  1. lista^.val:=p^.val;



e poi alla prima iterazione del ciclo l'assegnazione

Codice sorgente - presumibilmente Plain Text

  1. p^.val:=max;



dove vai a modificare il primo elemento della lista originale (p) con un valore (max) che ancora non e' stato definito

ti do un suggerimento funzionale (cioe' ti dico a parole i passi da eseguire, poi pero' devi essere tu a tradurlo in codice)

Caso 1: Ordinamento della lista originale

Passo 1: dichiari tre variabili di tipo punt per scorrere la lista (chiamiamole per esempio Idx, Min, e RelStart);

Passo2: assegni a RelStart il puntatore al primo elemento;

Passo 3: Inizio ciclo esterno, con condizione di uscita quando RelStart^.Next punta a Nil;

Passo 4: Ciclo interno in cui, col puntatore Idx scorri la lista alla ricerca dell'elemento col valore minimo, all'uscita del ciclo memorizzerai in Min il puntatore all'elemento col valore minimo;

Passo 5: uscito dal ciclo interno, scambi i valori degli elementi puntati da Min e da RelStart;

Passo 6: fai puntare RelStart all'elemento successivo;

Passo 7: Fine ciclo esterno, ritorna al passo 3, se non si verifica la condizione di uscita;

-----------------------------------------------------------------------

Caso 2: Creazione di una copia ordinata della lista

Passo 1: dichiari una variabile di tipo punt per scorrere la lista originale (chiamiamola per esempio Idx)
piu' altre due, sempre di tipo punt, per scorrere la nuova lista (chiamiamole per esempio IdxCopy e PrecIdxCopy);

Passo 2: inserisci nella nuova lista un elemento che avra' il valore del primo elemento della lista originale, inoltre fai puntare Idx all'elemento successivo al primo della lista originale;

Passo 3: Inizio ciclo esterno, con condizione di uscita quando Idx punta a Nil;

Passo 4: fai puntare IdxCopy al primo elemento della nuova lista;

Passo 5: Inizio ciclo interno, con condizione di uscita quando Il valore dell'elemento puntato da IdxCopy e' maggiore dell'elemento puntato da Idx;

Passo 6: finche' resti nel ciclo, ad ogni iterazione, fai puntare PrecIdxCopy all'elemento puntato da IdxCopy e poi fai puntare IdxCopy all'elemento successivo;

Passo 7: uscito dal ciclo interno, dovrai inserire un nuovo elemento (per esempio NewEl) nella nuova lista, che dovra' essere posizionato tra PrecIdxCopy e IdxCopy ( in pratica PrecIdxCopy^.Next dovra' puntare a NewEl, e NewEl^.Next dovra' puntare a IdxCopy)

Passo 8: fai puntare Idx all'elemento successivo;

Passo 9: Fine ciclo esterno, ritorna al passo 3, se non si verifica la condizione di uscita;

-----------------------------------------------------------------------

Tutto chiaro? Buon lavoro.

PS Ovviamente, se non ti scrivo il codice (per il quale avrei, tra l'altro, impiegato meno tempo), non e' per cattiveria, ma solo perche' soltanto facendolo tu da solo puoi sperare di imparare qualcosa di programmazione

PM Quote
Avatar
fabioser (Normal User)
Rookie


Messaggi: 59
Iscritto: 12/05/2012

Segnala al moderatore
Postato alle 16:05
Sabato, 04/08/2012
Gentile GigiSoft, so che mi hai già invitato a sviluppare il programma da solo ma, come forse avrai intuito, sto studiando il linguaggio Pascal da completo autodidatta, e trovo notevoli difficoltà con i puntatori e le liste, perciò provo a chiederti lo stesso se puoi essere così gentile da fornirmi la soluzione in codice sorgente poichè io non riesco ad elaborarla da solo. Mi sarebbe infinitamente utile per progredire nello studio degli ordinamenti nelle liste. Grazie infinitamente fino da ora se vorrai aiutarmi. Ciao!!!:asd:

PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo