Advertisement
RiccardoMontagnin

Esame 14 Luglio 2015

Jul 14th, 2015
429
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.20 KB | None | 0 0
  1. #include<iostream>
  2. #include<fstream>
  3. using namespace std;
  4.  
  5. /////////////////////////////////////////////////////////////////////////
  6. ///////////////////////////  FUNZIONI DATE  /////////////////////////////
  7. /////////////////////////////////////////////////////////////////////////
  8.  
  9. struct nodo{
  10.     int info;
  11.     nodo* next;
  12.    
  13.     nodo(int a=0, nodo* b=0){
  14.         info=a;
  15.         next=b;
  16.     }
  17.    
  18. };
  19.  
  20. struct nodoT{
  21.     int info;
  22.     nodoT* left,* right;
  23.    
  24.     nodoT(int a=0, nodoT* b=0, nodoT* c=0){
  25.         info=a;
  26.         left=b;
  27.         right=c;
  28.     }
  29.  
  30. };
  31.  
  32. //PRE=(alt>=0)
  33. nodo* costruisci_L(int alt){
  34.    
  35.     nodo* r=0;
  36.     while(alt){
  37.         r=new nodo(0,r);
  38.         alt--;
  39.     }
  40.     return r;
  41.  
  42. }
  43. //POST=(restituisce una lista con alt nodi con info=0)
  44.  
  45. nodoT*buildt(){
  46.     nodoT* f1=new nodoT(10);
  47.     nodoT* f2=new nodoT(20);
  48.     nodoT*I=new nodoT(15,f1,f2);
  49.     nodoT*R=new nodoT(2,I, new nodoT(23));
  50.     return R;
  51. }
  52. //restituisce un albero per provare la vostra F1
  53. //stampa gli alberi in forma lineare
  54. void stampa_l(nodoT *r, ofstream & OUT){
  55.     if(r){
  56.         OUT<<r->info<<'(';
  57.         stampa_l(r->left,OUT);
  58.         OUT<<',';
  59.         stampa_l(r->right, OUT);
  60.         OUT<<')';
  61.     }
  62.    
  63.     else
  64.         OUT<< '_';
  65. }
  66.  
  67. //stampa lista
  68. void stampa_L(nodo* x,ofstream& OUT){
  69.     if(x){
  70.         OUT<<x->info<<' ';
  71.         stampa_L(x->next,OUT);
  72.     }
  73.    
  74.     else
  75.         OUT<<endl;
  76. }
  77.  
  78.  
  79. /////////////////////////////////////////////////////////////////////////
  80. /////////////////////////  FUNZIONI CREATE  /////////////////////////////
  81. /////////////////////////////////////////////////////////////////////////
  82.  
  83. //PRE=(L lista corretta, vL = L)
  84. void azzera(nodo* L){
  85.     if(!L){             //Lista vuota
  86.         return;
  87.     }
  88.  
  89.     L->info=0;          //Azzera il campo info del nodo corrente
  90.     azzera(L->next);    //Azzera i successivi
  91. }
  92. //POST=(restituisce vL dove vL = L con tutti i campi info =0)
  93.  
  94. //PRE=(list(L) corretta, L=vL)
  95. void F0(nodo*L, bool & b){
  96.  
  97.     if(!L){     //Lista vuota o non da modificare
  98.         b=false;
  99.         return;
  100.     }
  101.  
  102.     F0(L->next, b);         //Scorri fino alla fine della lista
  103.  
  104.     if(!L->info && !b){     //Se il campo info di un nodo è 1 e b==false (ovvero la lista successiva è composta da solo nodi con campo info=1
  105.         L->info =1;             //Metti il campo info del nodo attuale a 1
  106.         azzera(L->next);        //Azzera i campi successivi
  107.         b = true;               //Imposta b a true (la lista non sarà più composta da soli nodi con campo info = 0
  108.         return;
  109.     }
  110.  
  111. }
  112. //POST=(b => lista(L) è ottenuta da lista(vL) facendo la trasformazione richiesta)&&(!b=> lista(vL) è tale che ogni nodo ha campo info=1 e lista(L)=lista(vL)
  113.  
  114. /*
  115.  
  116.     Dimostrazione della correttezza di F0 rispetto a PRE e POST date
  117.  
  118.     (1) Caso base = lista vuota
  119.         L non contiene alcun nodo quindi, paradossalmente, il campo info dei suoi nodi può essere considerato 1, e dunque b viene impostata a false => rispetta POST
  120.  
  121.     (2) Passo induttivo = lista corretta con almeno un nodo
  122.         L'invocazione ricorsiva di F0 rispetta PRE_F0 in quanto ci troviamo in un nodo definito e, di conseguenza, L->next e' una lista corretta alla quale non è stato
  123.         cambiato il valore di nessun campo info => PRE=(list(L) corretta, L=vL) rispettata
  124.  
  125.         L'invocazione ricorsiva di F0 rispetta anche POST_F0 in quanto se si ha un solo nodo quello successivo sarà vuoto e, come visto nel caso base (1) questa
  126.         casistica rispetta POST_F0.
  127.  
  128.         Ora vengono eseguite le istruzioni successive, ovvero:
  129.  
  130.         (a) Se il campo info del nodo considerato è uguale a 0 e la lista che parte da L->next è composta solamente da nodi con campo info = 1 (ovvero b == false),
  131.             allora il campo info del nodo attuale viene posto a 1, e vengono azzerati i campi info successivi (*), inoltre b viene posto a true per identificare che
  132.             non tutta la lista è composta da 1.
  133.  
  134.         (b) Se il campo info del nodo considerato è uguale a 1, non viene eseguito nulla, a significare che la lista è attualmente composta da soli nodi con campo
  135.             info = 1 (b==false).
  136.  
  137.         Entrambi i casi (a) e (b) rispettano POST_F0.
  138.  
  139.  
  140.         (*) All'interno di F0 viene utilizzata azzera. Vediamo di verificarne la correttezza rispetto a PRE_ric.
  141.  
  142.             Se il nodo di L considerato è stato posto a 1, significa che esso esiste e, dunque, L->next sara' una lista corretta => rispetta PRE_azzera
  143.  
  144.             Al ritorno, L->next, data POST_azzera, sara' composta da tutti i nodi con campo info = 0 => rispetta POST_azzera
  145.  
  146. */
  147.  
  148.  
  149. //PRE=(R albero corretto, vuoto)
  150. nodoT* aggiungi_nodo(nodoT* R, ifstream &INP){    //Aggiunge un nodo ad un nodo inesistente
  151.  
  152.     int x;              //Creo una variabile intera dove poter salvare il valore letto da INP
  153.     INP>>x;             //Leggo il valore
  154.     R=new nodoT(x);     //Creo un nuovo nodo con quel valore letto
  155.     return R;           //Restituisco l'indirizzo del nodo appena creato
  156.  
  157. }
  158. //POST=(restituisce l'indirizzo di un nuovo nodo R creato leggendo da INP il valore del campo info)
  159.  
  160. //PRE=(albero(R)corretto, 0<prof, INP ifstream definito, R=vR, INP contiene (almeno) 2(alt+1)-1 valori)
  161. nodoT * F1(nodoT* R, int alt, ifstream & INP){
  162.  
  163.     if(!R){                 //Se non c'e' la radice creala
  164.         int x;
  165.         INP>>x;
  166.         R = new nodoT(x);
  167.     }
  168.  
  169.     nodo* L=costruisci_L(alt);  //Costruisci la prima lista vuota
  170.     nodo* currL =L;             //Puntatore di riferimento all'interno di L
  171.     nodoT* currT =R;            //Puntatore di riferimento all'interno dell'albero R
  172.     bool b = true;              //Booleana per F0
  173.  
  174.     while(b){                   //Fintato che la lista L non e' composta tutta da 1 e non vi si puo' aggiungere piu' nulla
  175.  
  176.         /* R = (b == true => la lista L presenta almeno uno 0 al suo interno)*/
  177.  
  178.         currL = L;              //Imposta il puntatore all'interno di L all'inizio di L
  179.         currT = R;              //Imposta il puntatore all'interno dell'albero alla sua radice
  180.  
  181.         while(currL){                               //Data una lista la scorre tutta e aggiunge i nodi che non ci sono
  182.  
  183.             /* R=(currL non e' vuota)&&(mi trovo al nodo di R che si trova seguendo il percorso scritto dal primo nodo a quello attuale di L) */
  184.  
  185.             if(!currL->info){                                   //Se leggo 0
  186.                 if(!currT->left){                                   //Se non ho il ramo di sinistra
  187.                     currT->left = aggiungi_nodo(R->left, INP);          //Lo creo
  188.                 }
  189.                 currT = currT->left;                                //Mi sposto a sinistra
  190.             }
  191.  
  192.             else{                                               //Se leggo 1
  193.                 if(!currT->right){                                  //Se non ho il ramo di destra
  194.                     currT->right = aggiungi_nodo(R->right, INP);        //Lo creo
  195.                 }
  196.                 currT = currT->right;                               //Mi sposto a destra
  197.             }
  198.  
  199.             currL = currL->next;
  200.  
  201.         }
  202.  
  203.         F0(L, b);                                               //Aggiungo un 1 a L
  204.     }
  205.  
  206.         return R;
  207.  
  208. }
  209. //POST=(albero(R)è ottenuto da albero(vR) aggiungendo tutti i nodi non già presenti in albero(vR) di tutti i cammini di lunghezza alt, i campi info dei nodi sono
  210. //      letti da INP. I cammini vanno considerati partendo del cammino con soli 0, poi applicando F0 ripetutamente
  211.  
  212.  
  213. main(){
  214.    
  215.     ifstream IN("input");
  216.     ofstream OUT("output");
  217.     if(IN && OUT){
  218.        
  219.         int alt;
  220.    
  221.         IN>>alt;
  222.         nodo*L=costruisci_L(alt);
  223.         bool b=true;
  224.        
  225.         while(b){
  226.             stampa_L(L,OUT);
  227.             F0(L, b);
  228.         }
  229.  
  230.         nodoT*R=F1(0,alt,IN);
  231.         stampa_l(R,OUT);
  232.        
  233.         OUT<<endl;
  234.        
  235.         nodoT*K=buildt();
  236.         stampa_l(K,OUT);
  237.        
  238.         OUT<<endl;
  239.        
  240.         K=F1(K,alt,IN);
  241.         stampa_l(K,OUT);
  242.        
  243.         IN.close();
  244.         OUT.close();
  245.        
  246.     }
  247.  
  248.   else
  249.     cout<<"errore con i files";
  250.  }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement