Advertisement
Guest User

Compitino 1 a.a. 2018-19 - turno 1

a guest
Apr 9th, 2020
339
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.66 KB | None | 0 0
  1. /* ESEMPIO
  2. n_ele = 22
  3. lim1, lim2, lim3 = 5,3,3 (prodotto >= n_ele)
  4. A (visto a 3 dimensioni):
  5. 1  2  3
  6. 11 20 20  <---    
  7. 11 8  12
  8.  
  9. 10 11 12
  10. 20 12 15  <---
  11. 16 20 18
  12.  
  13. 19 20 21
  14. 22        <---
  15.        
  16. np=3
  17. P:
  18. 11 12 20
  19.  
  20. H-Fetta selezionata: 1  (7 elementi), nell'esempio le righe sono
  21.                                       indicate con <---
  22. OUTPUT ATTESO:
  23. start
  24. pattern rimasto 20
  25. La H-fetta 1 e' diventata:
  26. 20 20 20 15 22
  27. end
  28. */
  29.  
  30. //SVOLTO DA LUCA VERONESE PER L'INCONTRO TUTORATO DEL GIORNO 09/04/2020
  31. #include<iostream>
  32. using namespace std;
  33.  
  34. int dimHFetta(int i, int n_ele, int lim2, int lim3);
  35. //POST=(restituisce la dimensione della h-fetta i)
  36.  
  37. // PRE=(index indica l'indice dell'elemento della H-fetta di cui si vuole la distanza dal primo elmento della H-fetta)
  38. int pos(int index, int lim2, int lim3);
  39. //POST=(restituisce la distanza in X tra il primo elemento di una
  40. //H-fetta e l’elemento index di quella H-fetta)
  41.  
  42. void Stampa(int* inizioHF, int bene, int lim2, int lim3);
  43.  
  44. int main()
  45. {
  46.     int X[400], P[20], hf;      //gli elementi di P vanno cercati in H-fetta hf di X
  47.     int n_ele, nP;              //n° elementi inizializzati in X e in P
  48.     int lim1, lim2, lim3;       //n° di strati, righe, colonne di X
  49.  
  50.     cin >> n_ele;
  51.     for(int i = 0; i < n_ele; i++) {    //riempimento X[0..n_ele-1]
  52.         cin >> X[i];
  53.     }
  54.  
  55.     cin >> lim1 >> lim2 >> lim3 >> nP;
  56.     if(n_ele > lim1 * lim2 * lim3) {    //la correttezza richiede n_ele <= lim1*lim2*lim3
  57.         n_ele = lim1 * lim2 * lim3;
  58.     }
  59.     for(int i = 0; i < nP; i++) {       //riempimento P[0..nP-1]
  60.         cin >> P[i];
  61.     }
  62.  
  63.  
  64.     cout << "start" << endl;
  65.     cin >> hf;                          //selezione H-fetta da trattare
  66.     int dimH = dimHFetta(hf, n_ele, lim2, lim3);
  67.     int* inizioHF = X + (hf * lim3);    //inizio H-fetta da trattare (=inizio riga hf di strato 0)
  68.     int matchCount =0;                  //ultimo elemento di P ad essere stato trovato tra primi i elementi di vH-Fetta
  69.     /*PRE= i==0 && matchCount ==0
  70.     && X è array con n_ele elementi inizializzati, dove n_ele <= lim1*lim2*lim3
  71.     && vH-Fetta ha dimH elementi inizializzati
  72.     && Pattern ha nP elementi inizializzati
  73.     */
  74.    
  75.     for (int i=0; i<dimH; i++) {
  76.         /*R = (0<=i<=dimH)
  77.          *&& (tra i primi i elementi di vH-Fetta sono stati trovati nell'ordine tutti gli elementi di P[0..matchCount-1])
  78.          *&& (primi i-matchCount elementi di H-Fetta sono ottenuti eliminando nell'ordine ogni elemento di P[0..matchCount-1] dai primi i elementi di vH-Fetta)
  79.          */
  80.         /*N.B.'sono stati trovati nell'ordine' non significa anche "contigui"
  81.             dunque se matchCount = 3, P[0..matchCount-1] = {2,5,3}
  82.             allora i primi i elementi di vH-Fetta sono (prima seq. di interi) 2 (seconda seq. di int) 5 (terza seq.) 3 (quarta seq.)
  83.             e primi i - matchCount elementi di H-Fetta = (prima seq. ) (seconda seq.) (terza seq.) (quarta seq.)
  84.             dove prima seq. può contenere 5,3; seconda seq. può contenere 2,3; terza seq può contenere 2,5; quarta seq. può contenere 2,5,3
  85.         */
  86.         int k = pos(i,lim2,lim3);
  87.         if (matchCount == nP || inizioHF[k] != P[matchCount]) {
  88.             int h = pos(i-matchCount,lim2,lim3);
  89.             inizioHF[h] = inizioHF[k];
  90.         } else {
  91.             matchCount++;
  92.         }
  93.         /*PROVA DI CORRETTEZZA:
  94.     1- INIZIALIZZAZIONE (dimostriamo PRE => R)
  95.         i==0 && match==0
  96.       =>  (0<=i<=dimH) banalmente vera
  97.         i==0 && match==0 => (tutti gli elementi di P[0..matchCount-1] sono presenti nello stesso ordine tra i primi i elementi di vH-Fetta)
  98.       => banalmente vera (P[0..matchCount-1] e primi i elementi di vH-Fetta sono entrambi vuoti)
  99.         i==0 && match==0 => (primi 0 elementi di H-Fetta corrispondono a primi 0 elementi [...] tra i quali abbiamo eliminato 0 elementi [...])
  100.       => vera
  101.        
  102.         abbiamo dimostrato PRE => (i==0 && matchCount==0) => (parte1 && parte2 && parte3 di R) == R
  103.  
  104.     2- INVARIANZA  (R && cond => R)
  105.         (0<=i<=dimH) && (i<dimH)
  106.       => (0<=i+1<=dimH)
  107.  
  108.         assumendo parte2 e parte3 dell'invariante si ha che la parte2 e la parte3 valgono all'inizio dell'iterazione successiva qualunque ramo venga preso.
  109.         DIMOSTRAZIONE:
  110.         se valgono parte2 && parte3 && cond
  111.     se matchCount == nP (ramo if, 1° caso)
  112.             il pattern è già stato consumato.
  113.            
  114.             L'invariante assieme a matchCount == nP afferma che tra i primi i elementi di vH-Fetta sono già contenuti nell'ordine TUTTI gli elementi
  115.             del pattern, non rimangono altri elementi del pattern da cercare da i+1-esimo elemento di vH-fetta in poi.
  116.            
  117.             Dunque sono vere:
  118.             -parte2 di R in i+1:
  119.                 i primi i+1 elementi di vH-Fetta includono primi i elementi di vH-Fetta, tra i quali sono stati trovati
  120.                 tutti gli elementi di P[0..(matchCount)-1]. Inoltre tra i primi i+1 elementi di vH-Fetta non sono
  121.                 stati trovati nuovi elementi del pattern rispetto a iter. precedente (non ce ne sono più!)
  122.             -parte3 di R in i+1:
  123.                 non essendoci altri elementi del pattern da cercare oltre ai primi i elementi di vH-Fetta, si ha che aggiungendo
  124.                 i+1-esimo elemento di vH-Fetta agli i-matchCount elementi di H-Fetta questa corrisonde ancora alla sequenza
  125.                 ottenuta eliminando nell'ordine ogni elemento di P[0..(matchCount)-1] dai primi i+1 elementi di vH-Fetta.
  126.                
  127.             Abbiamo dimostrato che in questo caso vale parte2 && parte3 di R in (i+1).
  128.             Al termine dell'iterazione si incrementa i per mantenere invariante in iterazione successiva.
  129.             Ora dobbiamo ripetere dimostrazione per i restanti casi.
  130.    
  131.     se matchCount < nP && inizioHF[k] != P[matchCount] (ramo if, 2° caso)
  132.             i+1-esimo elemento di vH-Fetta è UGUALE a P[matchCount], allora matchCount non viene incrementato
  133.        
  134.         Dimostriamo con uno pseudo-formalismo che la sequenza {P[0..matchCount-1]} è CONTENUTA nell'ordine IN {primi i+1 elementi di vH-fetta}
  135.         Nel seguente pseudo-formalismo si abusa della notazione insiemistica ( {} indicano una sequenza e U indica concatenazione ),
  136.          si scrive una sola frase per riga e si scrive a lato del connettivo/operatore una giustificazione
  137.            
  138.             {P[0..matchCount-1]}
  139.         CONTENUTO ORDINATAMENTE IN (hyp: parte2 di R, che abbbiamo assunto vero)
  140.             {primi i elementi di vH-fetta}
  141.         CONTENUTO ORDINATAMENTE IN 
  142.             {primi i+1 elementi di vH-fetta}
  143.        
  144.             per affermare che vale la parte3 di R in iterazione successiva occorre affermare che
  145.         {primi i+1-matchCount elementi di H-Fetta} == {seq. ottenuta eliminando [...] P[0..matchCount-1] dai primi i+1 elementi di vH-Fetta}
  146.             dimostriamo questa proprietà facendo uso di alcune ipotesi (invariante ed esecuzione istruzioni del ciclo)
  147.            
  148.             {primi i+1-matchCount elementi di H-Fetta}
  149.         == (a seguito di assegnamento dell'i+1-esimo elemento di vH-Fetta in i+1-matchCount elementi di H-Fetta)
  150.             {primi i-matchCount elementi di H-Fetta} U {i+1-esimo elemento di vH-Fetta}
  151.         == (hyp: parte3 di R)
  152.             {seq. ottenuta eliminando [...] P[0..matchCount-1] dai primi i elementi di vH-Fetta} U {i+1-esimo elemento di vH-Fetta}
  153.         == (hyp: i+1-esimo elemento di vH-Fetta != P[matchCount], ovvero la condizione del ramo)
  154.             {seq. ottenuta eliminando [...] P[0..matchCount-1] dai primi i+1 elementi di vH-Fetta}
  155.            
  156.             Per proprietà transitiva di == e di CONTENUTO (ordinatamente) IN abbiamo ottenuto le affermazioni delle
  157.             righe 134 e 145, ovvero quelle che dovevamo ottenere per affermare parte2 e parte3 di R con i+1 al posto di i.
  158.             Al termine dell'iterazione si incrementa i per mantenere invariante in iterazione successiva.
  159.  
  160.     se  matchCount < nP && inizioHF[k] == P[matchCount]
  161.             i+1-esimo elemento di vH-Fetta è UGUALE a P[matchCount], allora matchCount viene incrementato al fine di mantenere R in iter. successiva
  162.            
  163.             Bisogna dimostrare:
  164.             R && cond && (matchCount < nP && inizioHF[k] == P[matchCount])
  165.           =>
  166.             {primi i+1-(matchCount+1) elementi di H-Fetta}=={seq. ottenuta eliminando P[0..matchCount] dai primi i+1 elementi di vH-Fetta} &&
  167.             && {P[0..matchCount]} contenuto ordinatamente in {primi i+1 elementi di vH-fetta}
  168.        
  169.       Dimostrazione R && cond && (matchCount < nP && inizioHF[k] == P[matchCount])=> parte2 (con i+1 al posto di i)
  170.            
  171.             {P[0..matchCount]}
  172.         ==
  173.             {P[0..matchCount-1]} U {P[matchCount]}
  174.         CONTENUTO ORDINATAMENTE IN (hyp: parte2 di R)
  175.             {primi i elementi di vH-fetta} U {P[matchCount]}
  176.         CONTENUTO ORDINATAMENTE IN (hyp: i+1-esimo elemento di vH-Fetta == P[matchCount], condizione del ramo in cui ci troviamo)
  177.             {primi i+1 elementi di vH-fetta}
  178.      
  179.       Dimostrazione R&& cond && matchCount<nP && inizioHF[k]==P[matchCount] => parte3 (con i+1 al posto di i)
  180.             {primi i+1-(matchCount+1) elementi di H-Fetta}
  181.         == (dall'aritmetica i+1-(matchCount+1) == i-matchCount)
  182.             {primi i-matchCount elementi di H-Fetta}
  183.         == (hyp: parte3 di R)
  184.             {seq. ottenuta eliminando P[0..matchCount-1] dai primi i elementi di vH-Fetta}
  185.         == (i+1-esimo elemento di vH-Fetta == P[matchCount]; dunque seq. ottenuta eliminando P[0..matchCount] dai primi i+1 elementi di vH-Fetta non contiene i+1-esimo elemento di vH-Fetta)
  186.             {seq. ottenuta eliminando P[0..matchCount] dai primi i+1 elementi di vH-Fetta}
  187.            
  188.         Abbiamo dimostrato anche in questo caso parte2 e parte3 R con i+1 e matchCount+1, ovvero l'affermazione di righe 164-167.
  189.  
  190.         Oltre a i, in questo caso si incrementa anche matchCount per mantenere invariante all'inizio di iter. successiva
  191.        
  192.     ALLA FINE ABBIAMO OTTENUTO che SE SI ENTRA NEL CICLO (vale R && cond)
  193.      parte2 e parte3 DI R valgono all'inizio dell'iterazione successiva qualunque ramo venga preso.
  194.     Ricordandoci che in righe 105-106 abbiamo dimostrato che se vale R && cond vale parte1 in iterazione successiva,
  195.      siamo riusciti a dimostrare R && cond => (parte1 && parte2 && parte3 di R[i+1]) == R[i+1]
  196.  
  197.     3- TERMINAZIONE (R && !cond => POST)
  198.         (0<=i<=dimH) && !(i<dimH) => i==dimH
  199.        
  200.         POST1 e POST2 (prima e seconda parte di POST) si ottengono sostituendo dimH a i in parte2 e parte3 di R
  201.    
  202.         (tra i primi i elementi di vH-Fetta sono stati trovati nell'ordine tutti gli elementi di P[0..matchCount-1])
  203.             && i==dimH && vH-Fetta aveva dimH elementi
  204.     =>  (in vH-Fetta sono stati trovati nell'ordine tutti gli elementi di P[0..matchCount-1])
  205.  
  206.         (primi i-matchCount elementi di H-Fetta sono ottenuti eliminando nell'ordine ogni elemento di P[0..matchCount-1] dai primi i elementi di vH-Fetta) && i==dimH
  207.     => (primi dimH-matchCount elementi di H-Fetta sono ottenuti eliminando nell'ordine ogni elemento di P[0..matchCount-1] dai primi i elementi di vH-Fetta)
  208.  
  209.     ABBIAMO DIMOSTRATO  R && !cond => POST1 && POST2 == POST
  210.  
  211.  
  212.     POST=(tutti gli elementi di P[0..matchCount-1] erano presenti nello stesso ordine in vH-Fetta)
  213.         &&  (dimH-matchCount elementi più a sinistra di H-Fetta = vH-Fetta a cui è stata eliminata la sequenza P[0..matchCount-1], a partire da sinistra)
  214.  
  215.     */
  216.     }
  217.     if (matchCount == nP) {
  218.         cout << "pattern consumato tutto";
  219.     } else {
  220.         cout << "pattern rimasto ";
  221.         for (int i = matchCount; i < nP; i++) {
  222.             cout << P[i] << ' ';
  223.         }
  224.     }
  225.     cout << "\nLa H-fetta " << hf << " e' diventata:" << endl;
  226.     Stampa(inizioHF, dimH - matchCount, lim2, lim3);
  227.     cout << "end" << endl;
  228.     return 0;
  229. }
  230.  
  231. int dimHFetta(int hf, int n_ele, int lim2, int lim3) {
  232.     int nsp = n_ele / (lim2 * lim3);    //numero strati pieni
  233.     int eus = n_ele % (lim2 * lim3);    //elementi dell'ultimo strato
  234.     int rpus = eus / lim3;              //(numero) righe piene ultimo strato
  235.     int ur = eus % lim3;                //(numero di elementi nell') ultima riga
  236.  
  237.     int dimH = lim3 * nsp;              //lunghezza minima di una H-fetta (se hf > rpus)
  238.     if (hf < rpus) {
  239.         dimH += lim3;
  240.     } else if (hf == rpus) {
  241.         dimH += ur;
  242.     }
  243.  
  244.     return dimH;
  245. }
  246.  
  247. int pos(int index, int lim2, int lim3) {
  248.     return (index/lim3)*lim2*lim3 + (index%lim3);
  249. }
  250.  
  251. void Stampa(int* inizioHF, int dim, int lim2, int lim3) {
  252.     for (int i = 0; i < dim; i++) {
  253.         int b = pos(i, lim2, lim3);
  254.         cout << inizioHF[b] << ' ';
  255.     }
  256.     cout << endl;
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement