Advertisement
madegoff

06ex

Jan 8th, 2024
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.32 KB | None | 0 0
  1. /*
  2. Zur Abgabe einen branch `iprg-b06` erstellen und pushen, in dem als einzige Datei die `06ex.c` liegt.
  3. */
  4.  
  5. /*
  6. Um die Tests für dieses Blatt zu kompilieren und zu starten, führen Sie den folgenden Befehl aus:
  7. cc -std=c11 -g -Wall -Werror 06ex_test.c -o 06ex_test.o -lm && ./06ex_test.o
  8.  
  9. Wir empfehlen, mit möglichst streng eingestelltem valgrind zu testen, denn so testen wir auch auf dem Server:
  10. cc -std=c11 -g -Wall -Werror 06ex_test.c -o 06ex_test.o -lm && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./06ex_test.o
  11. */
  12.  
  13. #include "array_visualizer.h"
  14. #include <stdio.h>
  15. #include <stdbool.h>
  16. #include <stdlib.h>
  17.  
  18. /*
  19. Aufgabe 1:
  20. Machen Sie sich in dieser Aufgabe mit dem `Visualizer` (siehe array_visualizer.h) vertraut.
  21. Nutzen Sie die `visualizer_append_array` Funktion damit die Tests durchlaufen.
  22.  
  23. Tipp 1: Die erste Zeile im erzeugten Bild stellt das Eingabearray dar.
  24. */
  25. void warmup(Visualizer *v, uint8_t *arr, size_t len) {
  26.  
  27.     for(int i = 0; i < len; i++){
  28.         visualizer_append_array(v,arr);
  29.         uint8_t first = arr[0];
  30.         for(int j = 0; j < len; j++){
  31.             arr[j] = arr[j+1];
  32.         }
  33.         arr[len-1] = first;
  34.     }
  35.  
  36. }
  37.  
  38. /*
  39. Aufgabe 2:
  40. Bringen Sie die Tests zum durchlaufen.
  41.  
  42. Tipp 1: Die erste Zeile im erzeugten Bild stellt das Eingabearray dar.
  43. Tipp 2: Es handelt sich um eine Abwandlung von iterativem Mergesort.
  44. Tipp 3: `len` ist immer eine Dreierpotenz, damit Sie sich nicht mit Rundungsdetails herumschlagen brauchen.
  45. */
  46.  
  47. void merge_3_arrays(uint8_t* arrA, uint8_t p, uint8_t r1, uint8_t r2, uint8_t r3){ //zusammenfuegen von arrays arrA[p, ... , r1], arrA[r1+1, ... , r2], arrA[r2+1, ... , r3]
  48.  
  49.     printf("\n start merge\n");
  50.  
  51.     int len = r3-p+1;
  52.  
  53.     uint8_t arrB[len]; //hilfsarray
  54.     uint8_t i = p, j = r1+1, k = r2+1;
  55.     int b = 0; //counter fuer array B
  56.  
  57.     uint8_t min; //hilfsvariable fuer die kleinste (von drei) zahl
  58.     int min_pos; //zeigt an, aus welchem array teil diese zahl genommen wird (um in diesem arraysteil den counter zu erhoehen)
  59.  
  60.     while(i<=r1 && j<=r2 && k<=r3){ //solange eintraege af allen 3 seiten
  61.  
  62.         //erster vergleich
  63.         if(arrA[i] <= arrA[j]){
  64.             min = arrA[i];
  65.             min_pos = 1; //aus dem ersten teil des arrays genommen
  66.         }
  67.         else{
  68.             min = arrA[j];
  69.             min_pos = 2; //aus dem zweiten teil des arrays genommen
  70.         }
  71.  
  72.         //zweiter vergleich
  73.         if(arrA[k] <= min){
  74.             min = arrA[k];
  75.             min_pos = 3; //aus dem dritten teil des arrays genommen
  76.         }
  77.         /*else{
  78.             min = min;
  79.             min_pos = min_pos;
  80.         }
  81.         */
  82.  
  83.         //kleinste zahl gefunden, nun in den hilfsarray hinschreiben
  84.  
  85.         arrB[b] = min;
  86.         printf("schreibe in array: %d\n", min);
  87.         b++; // counter fuer arrB erhoehen
  88.  
  89.         //welcher counter fuer arrA muss erhoeht werden?
  90.         if(min_pos == 1) i++;
  91.         else if(min_pos == 2) j++;
  92.         else k++;
  93.  
  94.     }
  95.  
  96.     //wenn man aus der schleife austritt, kann das aus 3 gruenden passieren: i>r1, j>r2, k>r3 (oder kombi von diesen drei)
  97.     //wir betrachten also (solange es sie noch gibt) die ungemergten arrays teile, die nun nicht 3 sondern maximal 2 sind
  98.     //das ist gleich wie 2 arrays zu mergen und das koennen wir bereits
  99.  
  100.     // Situation (a) : i > r1
  101.     while(j<=r2 && k<=r3){
  102.         if(arrA[j] <= arrA[k]){
  103.             arrB[b] = arrA[j];
  104.             printf("schreibe in array: %d\n", arrA[j]);
  105.             j++;
  106.         }
  107.         else{
  108.             arrB[b] = arrA[k];
  109.             printf("schreibe in array: %d\n", arrA[k]);
  110.  
  111.             k++;
  112.         }
  113.         b++;
  114.     }
  115.  
  116.     // Situation (b) : j > r2
  117.     while(i<=r1 && k<=r3){
  118.         if(arrA[i] <= arrA[k]){
  119.             arrB[b] = arrA[i];
  120.             printf("schreibe in array: %d\n", arrA[i]);
  121.  
  122.             i++;
  123.         }
  124.         else{
  125.             arrB[b] = arrA[k];
  126.             printf("schreibe in array: %d\n", arrA[k]);
  127.  
  128.             k++;
  129.         }
  130.         b++;
  131.     }
  132.  
  133.     // Situation (c) : k > r3
  134.     while(i<=r1 && j<=r2){
  135.         if(arrA[i] <= arrA[j]){
  136.             arrB[b] = arrA[i];
  137.             printf("schreibe in array: %d\n", arrA[i]);
  138.             i++;
  139.         }
  140.         else{
  141.             arrB[b] = arrA[j];
  142.             printf("schreibe in array: %d\n", arrA[j]);
  143.             j++;
  144.         }
  145.         b++;
  146.     }
  147.  
  148.     //nach diesen manipulationen sind zumindest 2 arraysteile in den hilfsarray kopiert, es kann aber sein dass noch irwelche eintraege uebrig geblieben sind
  149.  
  150.     //Eintraege im ersten array teil
  151.     while(i<=r1){
  152.         arrB[b] = arrA[i];
  153.         printf("schreibe in array: %d\n", arrA[i]);
  154.         b++;
  155.         i++;
  156.     }
  157.  
  158.     //Eintraege im zweiten array teil
  159.     while(j<=r2){
  160.         arrB[b] = arrA[j];
  161.         printf("schreibe in array: %d\n", arrA[j]);
  162.         b++;
  163.         j++;
  164.     }
  165.  
  166.     //Eintraege im dritten array teil
  167.     while(k<=r3){
  168.         arrB[b] = arrA[k];
  169.         printf("schreibe in array: %d\n", arrA[k]);
  170.         b++;
  171.         k++;
  172.     }
  173.  
  174.  
  175.     printf("\n array B:\n");
  176.     for(int t = 0; t<len; t++){
  177.         printf("B[%d] = %d\n", t, arrB[t]);
  178.     }
  179.  
  180.     //nun sind alle eintraege nach arrB zugewiesen und arrB kann in arrA kopiert werden
  181.  
  182.  
  183.  
  184.     int help_counter = 0;
  185.     for(int q = p; q<=r3; q++){
  186.  
  187.         arrA[q] = arrB[help_counter];
  188.         help_counter++;
  189.     }
  190.  
  191.     printf("\n array A :\n");
  192.     for(int t = p; t<=r3; t++){
  193.         printf("A[%d] = %d\n", t, arrA[t]);
  194.     }
  195.  
  196. }
  197.  
  198. void sort_it(Visualizer *v, uint8_t *arr, size_t len) {
  199.  
  200.     visualizer_append_array(v,arr);
  201.  
  202.     int r1,r2,r3; //hilsvariablen fuer arraygrenzen
  203.     int step = 1; //erstmal : drei arrays laenge 1 (step = 1), dann - 3 arrays laenge 3 (step = 3)
  204.     while(step < len){
  205.         int left = 0; //linke grenze initialisiert
  206.  
  207.         while(left <= len - step){ //sortieren
  208.  
  209.             r1 = left+step-1; // erste rechte grenze
  210.             r2 = left+2*step-1; // zweite rechte grenze
  211.             r3 = left+3*step-1; // dritte rechte grenze
  212.  
  213.             //nun muessen wir drei arrays laenge step zusammenfuegen
  214.             merge_3_arrays(arr, left, r1, r2, r3);
  215.             visualizer_append_array(v,arr);
  216.             left = left+3*step; // linke grenze verschieben
  217.         }
  218.  
  219.         step = step*3;
  220.     }
  221. }
  222.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement