Advertisement
framp

Programmazione 1

Mar 18th, 2013
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.11 KB | None | 0 0
  1. Pointer arithmetic:
  2. type X [10][5][10];
  3. d = { "bool": 1, "char": 1, "int": 4, "float": 4, "double": 8 };
  4.     X:
  5.         T=type(*)[5][10],
  6.         sizeof(T) = 5*10,
  7.         I
  8.     X+k (X[k]):
  9.         T=type(*)[5][10],
  10.         sizeof(T) = 5*10*d[type],
  11.         I+k(5*10)*d[type]
  12.     *(X+k)+j (X[k][j]):
  13.         T=type(*)[10],
  14.         sizeof(T) = 10*d[type],
  15.         I+k(5*10)*d[type]+j(10)*d[type]
  16.     *(*(X+k)+j)+i (X[k][j][i]):
  17.         T=type(*),
  18.         sizeof(T) = d[type],
  19.         I+k(5*10)*d[type]+j(10)*d[type]+i*d[type]
  20.  
  21. int ex_1(){
  22.     char X[10][5][10];
  23.     cout << (int) X << " " << typeid(X).name() << " char (*)[5][10]\n";
  24.     cout << (int) (*(*X-4)+2) << " == " << (((int) X)-4*10*1+2*1)
  25.          <<  " " << typeid((*(*X-4)+2)).name() << "  char (*)\n";
  26.     cout << (int) X[-1] << " == " << (((int) X)-1*5*10*1)
  27.          <<  " " << typeid(X[-1]).name() << " char (*)[10]\n";
  28.     // both are undefined
  29. }
  30.  
  31. Javascript solving algorithm:
  32. console.log(parse("X+3=", "char", [10,5,10]));
  33. console.log(parse("*(X+3)+4=", "char", [10,5,10]));
  34. console.log(parse("*(*(X+3)+4)+5=", "char", [10,5,10]));
  35. console.log(parse("*(*(X)-4)+2=", "char", [10,5,10]));
  36.  
  37. function parse(string, type, array){
  38.     var d = { "bool": 1, "char": 1, "int": 4, "float": 4, "double": 8 };
  39.     var ref = string.indexOf("*(");
  40.     array.shift();
  41.  
  42.     var re = (ref!=-1) ?
  43.             /\*\(X([\+\-]{0,1}[0-9]*)\)/gi :
  44.             /X([\+\-][0-9]*)/gi;
  45.     while (match = re.exec(string))
  46.         string += [match[1] || '+0', array.join('*'), d[type]].join('*');
  47.        
  48.     return (ref!=-1) ?
  49.         parse(string.replace(re, 'X'), type, array) :
  50.         string .replace(re, 'I')
  51.                  .replace(/X/gi, 'I')
  52.                  .replace('=', '');
  53. }
  54.  
  55.  
  56.  
  57. Reverse engineering:
  58. Find out errors, read the code.
  59.  
  60. Errors:
  61. 1) int & f(int a){ return a; } // a is local
  62. 2) int & f(){ int b; return b; } // b is local
  63. 3) int & f(int & a){ return a+1; } // a+1 is const, can't be referenced
  64. 4) int * F(int *a){ int b; a=&b; return a; } // b is local
  65.  
  66. int *p
  67. 1) *p; // segmentation fault
  68.  
  69. int a=6, *p = &a;
  70. 1) p = 6; // p is int *, 6 is int
  71. 2) p = a-6; // 0 is legal but compiler doesn't know
  72. p = 0;
  73. 1) *p = a // segmentation fault
  74.  
  75.  
  76. int *f(int **p){
  77.     int b=3,*x=&b;
  78.     **p=b;
  79.     x=*p;
  80.     return x;
  81. }
  82. int ex_2(){
  83.     int y=5, b=2,*q=&b;
  84.     *f(&q)=y*2;
  85.     cout << b << "\n";
  86.     /* G -> global (main), L -> local (f)
  87.       L-value    Name       R-value
  88.       10        Gy      5
  89.       11        Gb      2
  90.       12        Gq      11
  91.       13        Lp      12
  92.       14        Lb      3
  93.       15        Lx      14
  94.      
  95.       **p = b
  96.       Gb = Lb = 3
  97.      
  98.       x = *p
  99.       Lx = &q
  100.      
  101.       *f(&q) = y*2
  102.       *q = y*2 = 10
  103.      */
  104. }
  105.  
  106. Iterative functions:
  107. Write the code, write PRE, POST and R
  108.  
  109. void M(int(*A)[20], int * Inizio, int limite, int &r, int &k)
  110. {
  111.     /* PRE: A è un array A[limite][20] con limite*20 elementi definiti,
  112.      * Inizio è un array Inizio[limite] con limite elementi definiti,
  113.      * limite>0
  114.      */
  115.      
  116.     /* R: min è l'elemento con il numero minore trovato in A[0..i-1],
  117.      * r e k sono i  suoi indici
  118.      */
  119.     int min = INT_MAX;
  120.     for (int i=0; i<limite; i++)
  121.     {
  122.         if (Inizio[i]<20 && A[i][Inizio[i]]<min){
  123.             min = A[i][Inizio[i]];
  124.             r = i;
  125.             k = Inizio[i];     
  126.         }
  127.     }
  128.     Inizio[r]++;
  129.    
  130.     /* POST: min è l'elemento con il numero minore trovato in A,
  131.      * r e k sono i  suoi indici
  132.      * Inizio[r] viene incrementato di 1
  133.      *
  134.      */
  135. }
  136.  
  137. int * F(int(*A)[20],int limite)
  138. {
  139. int *R=new int[limite*20], *Inizio=new int[limite], r=0,k=0;
  140. for(int i=0; i<limite; i++) Inizio[i]=0;
  141. for(int i=0; i<limite*20; i++)
  142. {
  143. M(A,Inizio,limite,r,k);
  144. R[i]=A[r][k];
  145. }
  146. delete[] Inizio;
  147. return R;
  148. }
  149.  
  150. int main(){
  151.     int A[5][20];
  152.     int limite = 5;
  153.     for (int i=0; i<limite; i++)
  154.     {
  155.         for (int k=0; k<20; k++)
  156.         {
  157.             A[i][k] = (k+1)*10 + (i+1);
  158.             cout << A[i][k] << " ";
  159.         }
  160.         cout << "\n";
  161.     }
  162.     cout << "\n";
  163.    
  164.     int * R = F(A, 5);
  165.    
  166.     for (int i=0; i<limite*20; i++)
  167.         cout << *(R + i) << (((i+1)%20) ? " " : " \n");
  168.     cout << "\n";
  169. }
  170.  
  171. struct nodo{int info; nodo* next;};
  172.  
  173. void append(nodo *& L, int value)
  174. {
  175.     if (L)
  176.     {
  177.         append(L->next, value);
  178.     }else{
  179.         L = new nodo;
  180.         L->info = value;
  181.     }
  182. }
  183. void append(nodo *& L, nodo * value)
  184. {
  185.     if (L)
  186.         append(L->next, value);
  187.     else
  188.         L = value;
  189.  
  190. }
  191. int count(nodo *L)
  192. {
  193.     if (L)
  194.         return 1+count(L->next);
  195.     else
  196.         return 0;
  197. }
  198.  
  199.  
  200. void print(nodo * L)
  201. {
  202.     if (L)
  203.     {
  204.         cout << L->info << ((L->next) ? "->" : "");
  205.         print(L->next);
  206.     }else{
  207.         cout << "\n";
  208.     }
  209. }
  210.  
  211. void estrae(nodo*&L, nodo*N)
  212. {
  213.     /*
  214.      * PRE: L è una lista valida != 0,
  215.      *     N è un nodo di L
  216.      */
  217.     nodo ** myL = &L;
  218.     /*
  219.      * R: N non è uno degli elementi precedenti a myL
  220.      * Condizione d'uscita: myL è N
  221.      */
  222.     while (N!=*myL)
  223.         myL = &((*myL)->next);
  224.     *myL = (*myL)->next;
  225.     /*
  226.      * POST: L non contiene più l'elemento N
  227.      */
  228. }
  229. nodo* MI(nodo*&L, int*P, int dim_P)
  230. {
  231. nodo** M=new nodo*[dim_P];
  232. int n=0;
  233. nodo* origin=L;
  234. while(origin && n<dim_P)
  235. {
  236. if(origin->info==P[n])
  237. {
  238. M[n]=origin;
  239. n++;
  240. }
  241. origin=origin->next;
  242. }
  243. nodo* E= 0,*fine;
  244. if(n==dim_P)
  245. {
  246. E=fine=M[0];
  247. estrae(L,M[0]);
  248. for(int i=1; i<dim_P;i++)
  249. {
  250. estrae(L,M[i]);
  251. fine->next=M[i];
  252. fine=M[i];
  253. }
  254. fine->next=0;
  255. }
  256. delete[] M;
  257. return E;
  258. }
  259.  
  260. int main()
  261. {
  262.     nodo * L = 0;
  263.     append(L, 1);
  264.     append(L, 2);
  265.     append(L, 3);
  266.     append(L, 1);
  267.     append(L, 2);
  268.     int P[] = {1, 1};
  269.     int dim_P = 2;
  270.     print(MI(L, P, dim_P));
  271.     print(L);
  272. }
  273.  
  274.  
  275. Recursive functions:
  276. Write the code, write PRE, POST and demostrate by induction
  277.  
  278. Esercizio cancellato perchè considerato da Filè “eccessivamente complicato”
  279.  
  280. /* Dimostrazione:
  281.  * Casi base:
  282.  * 1) A contiene una lista vuota e non ha elementi successivi:
  283.  *      viene ritornato 0 (rispettando la POST)
  284.  * 2) A contiene una lista vuota:
  285.  *      la ricerca prosegue sull'elemento successivo;
  286.  *      abbiamo escluso il caso in cui A->next non sia valido quindi
  287.  *      la PRE è rispettata.
  288.  * 3) A non ha elementi successivi:
  289.  *      A è l'unico elemento e viene ritornato A (rispettando la POST)
  290.  *
  291.  * In tutti gli altri casi:
  292.  *      Se A ha il primo numero minore del corrispettivo in A->next
  293.  *      A e A->next vengono scambiati in modo che A->next sia sempre
  294.  *      la lista con il numero minore. Anche nel caso in cui A->next
  295.  *      contenga una lista vuota, i due numeri vengono scambiati:
  296.  *      A->next, quindi, contiene sempre una lista non vuota.
  297.  *
  298.  *      In seguito viene chiamata la funzione ricorsivamente passando
  299.  *      come parametro A->next. La PRE è rispettata in quanto sia A che
  300.  *      A->next sono liste di nodoP valide e diverse da zero.
  301.  *     
  302.  *      Il caso più semplice, quello in cui A->next ha solo un elemento
  303.  *      successivo, può essere ricondotto al caso base 3: la funzione
  304.  *      ricorsiva si limiterà a ritornare A->next stesso.
  305.  *      La funzione ritornerà quindi A->next che, come abbiamo già visto
  306.  *      è minore in ogni caso ad A. La POST è rispettata.
  307.  *     
  308.  *      Ogni caso più complesso, con un diverso numero elementi
  309.  *      successivi, può essere ricondotto al caso base 3.
  310.  */
  311.  
  312. void H(nodoP* A, nodo*& R)
  313. {
  314. nodoP* x=G(A);
  315. if(x)
  316. {
  317. nodo*y=x->info;
  318. x->info=y->next;
  319. R=y;
  320. H(A,R->next);
  321. }
  322. else
  323. R=0;
  324. }
  325.  
  326. int main(){
  327.     nodoP * A = 0;
  328.    
  329.     for (int i=0; i<5; i++)
  330.     {
  331.         nodo * B = 0;
  332.         for (int k=0; k<20; k++)
  333.         {
  334.             append(B, (i+1)+(k+1)*10);
  335.         }
  336.         print(B);
  337.         append(A, B);
  338.     }
  339.    
  340.     nodo * R = 0;
  341.     H(A, R);
  342.     print(R);
  343. }
  344.  
  345. struct nodo{char info; nodo* next;};
  346.  
  347. void append(nodo *& L, char value)
  348. {
  349.     if (L)
  350.     {
  351.         append(L->next, value);
  352.     }else{
  353.         L = new nodo;
  354.         L->info = value;
  355.     }
  356. }
  357. void append(nodo *& L, nodo * value)
  358. {
  359.     if (L)
  360.         append(L->next, value);
  361.     else
  362.         L = value;
  363.  
  364. }
  365. int count(nodo *L)
  366. {
  367.     if (L)
  368.         return 1+count(L->next);
  369.     else
  370.         return 0;
  371. }
  372.  
  373.  
  374. void print(nodo * L)
  375. {
  376.     if (L)
  377.     {
  378.         cout << L->info << ((L->next) ? "->" : "");
  379.         print(L->next);
  380.     }else{
  381.         cout << "\n";
  382.     }
  383. }
  384.  
  385.  
  386. nodo* M(nodo*&L, char*P, int dim_P, bool &ok){
  387.     /*PRE: L è una lista valida !=0
  388.      *     P è un array che contiene dim_P elementi validi
  389.      *     dim_P>0
  390.      */
  391.     nodo * K = 0;
  392.     if (L->info == *P)
  393.     {
  394.         append(K, L->info);
  395.          
  396.         if (ok)
  397.             L = L->next;
  398.  
  399.         if (dim_P!=1 && L->next)
  400.             append(K, M(L->next, P+1, dim_P-1, ok));
  401.  
  402.     }else{
  403.         if (L->next)
  404.             append(K, M(L->next, P, dim_P, ok));
  405.     }
  406.     if (!ok && count(K)==dim_P)
  407.     {
  408.         ok = !ok;
  409.         M(L, P, dim_P, ok);
  410.         ok = !ok;
  411.         return K;
  412.     }else
  413.         return 0;
  414.        
  415.     /* POST: L non contiene gli elementi verificati dal pattern (non
  416.      * necessariamente contiguo) P, K contiene gli elementi verificati.
  417.      */
  418. }
  419. /* Dimostrazione:
  420.  * Casi base:
  421.  * 1) dim_P = 1 e avviene un match: K contiene soltanto l'elemento
  422.  * corrente che viene ritornato dalla funzione. Subito prima del return
  423.  * viene chiamata la funzione M con gli stessi L, P e dim_P della
  424.  * funzione corrente (la PRE è rispettata) con il parametro ok true.
  425.  * Quando ok è true la funzione si limita ad eliminare i valori presenti
  426.  * P. In questo caso provvede ad eliminare l'unico nodo contenuto in K.
  427.  * Anche La POST è quindi rispettata.
  428.  *
  429.  * 2) L->next == 0: non ci sono elementi successivi nella lista; il
  430.  * controllo termina. Se non è avvenuto un match count(K) non potrà mai
  431.  * essere uguale a dim_P. La funzione ritornerà zero, rispettando la
  432.  * POST.
  433.  *
  434.  * In tutti gli altri casi:
  435.  * La funzione può essere ricondotta sempre al caso 1 o al caso 2,
  436.  * rispettivamente quando la funzione verifica l'ultimo elemento del
  437.  * pattern e quando la funzione termina di controllare L senza aver
  438.  * trovato tutti i matches necessari.
  439.  * La funzione infatti si invoca ricorsivamente modificando P e dim_P
  440.  * in base al match del valore corrente (andando quindi a controllare
  441.  * l'elemento successivo del pattern nell'invocazinoe ricorsiva) e
  442.  * controllando che il match non sia l'ultimo match richiesto.
  443.  * I match presenti nei nodi successivi vengono aggiunti a K.
  444.  * Prima del termine di esecuzione della funzione viene confrontato
  445.  * il numero di elementi contenuti in K e il numero di elementi del
  446.  * pattern; se il pattern è stato verificato viene invocata M con
  447.  * ok==true e i valori verificati dal pattern vengono eliminati.
  448.  */
  449.  
  450. int main()
  451. {
  452.     nodo * L = 0;
  453.     append(L, 'a');
  454.     append(L, 'b');
  455.     append(L, 'c');
  456.     append(L, 'a');
  457.     append(L, 'b');
  458.     char P[] = {'a', 'd',  'a'};
  459.     int dim_P = 2;
  460.     bool ok = false;
  461.     print(M(L, P, dim_P, ok));
  462.     print(L);
  463. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement