Problem mit Selectionsort

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
canlot
Beiträge: 393
Registriert: Di Mär 08, 2011 11:01 pm
Wohnort: NRW

Problem mit Selectionsort

Beitrag von canlot » Di Mär 08, 2011 11:21 pm

Hallo Zusammen.
Ich habe ein Programm geschrieben dass die Zahlen nach Reihenfolge sortieren soll und zwar absteigend.
Das Programm läuft solange man keine doppelte Werte hat und der Wert b hat merkwürdigen Einfluss auf das ganze, manche Zahlen akzeptiert er und manchen nicht, d.h. das bei manchen die richtigen Ergebnisse rauskommen und bei manchen nicht.
Hat jemand vielleicht ein Lösungsvorschlag?

Tut mir Leid wegen dem unleserlichen Code.

Code: Alles auswählen

#include <stdio.h>

        int main(void)
        {
            int zaeler =0;
            const int big = 10;
            int arr[big];
            int newar[big];
            int anzahl = 0;

            int a = 0,b = 0;
            int temp = 0;
            
            // Arrays deklarieren
            arr[0] = 345;
            arr[1] = 435;
            arr[2] = 150;
            arr[3] = 45;
            arr[4] = 16;
            arr[5] = 3070;
            arr[6] = 165;
            arr[7] = 453;
            arr[8] = 166;
            arr[9] = 300;
                
            while(zaeler < big)
            {
                a = 0;
                b = big;
                // b ist ein komischer Wert, der anscheinend zum Teil nicht gebrauch wird
                    while (a < big)
                    {
                        if(temp == 0)
                        {
                            if (arr[a] > arr[b])
                            {
                                b = a;
                            }
                        }
                        else
                        {
                        if (arr[a] > arr[b] && arr[a] < temp)
                            {
                                b = a;
                            }
                        }
                        a++;
                    }

                    newar[anzahl] = arr[b];
                    anzahl++;
                    temp = arr[b];
                    zaeler++;
            }

            zaeler = 0;
            while(zaeler < big)
            {
            printf("%d\n",newar[zaeler]);
            
            zaeler++;
            }
            
            return 0;
        }
Zuletzt geändert von Kerli am Mi Mär 09, 2011 12:16 am, insgesamt 1-mal geändert.
Grund: Titel (war "Sort-Algorithmus")

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Sort-Algorithmus

Beitrag von Kerli » Mi Mär 09, 2011 12:14 am

Hallo & Willkommen im Forum!

Dein 'b' ist definitiv problematisch, da du es am Anfang auf 'big' setzt, was aber in deinen Arrays ein Index über dem Maximum ist und dir daher Speichermüll liefern wird. Deiner Formulierung nach ist der Code nicht von dir. Ich würde dir bei einem so kurzem Code empfehlen zuerst genau nachzuvollziehen wie der Algorithmus funktioniert und ihn anschließend selbstständig zu implementieren. Dabei lernst du am meisten. Ein Beispielimplementierung mit Erklärungen zu Selectionsort (So nennt man den Algorithmus den du implementieren wolltest) findest du in unserem Wiki.
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Problem mit Selectionsort

Beitrag von Dirty Oerti » Mi Mär 09, 2011 12:46 am

Prinzipiell passt das schon :)
Ich hab mir das jetzt mal angeguckt, und das Problem liegt hier begraben:

Code: Alles auswählen

      if (arr[a] > arr[b] && arr[a] < temp)
Es kann (durchaus!) vorkommen, dass arr == temp, und dann stehst du da, weil dann ändert sich dein b nicht mehr.

Auch solltest du

Code: Alles auswählen

b = big;
nicht machen, denn dann rufst du kurz danach

Code: Alles auswählen

arr[big]
auf und das liegt nicht mehr im Array!

Ich hatte versucht, deinen Code so umzuschreiben (mit Kommentaren), dass es läuft und gleichzeitig noch erkennbar ist, was ich geändert hab.
Aber das hilft dir nichts, wenn ich dir jetzt den fertigen Code vorlege, da lernst du nichts daran.

Ich denke, es ist gut, wenn du dir mal den Code im Wiki anguckst.
Der ist anders (effektiver) als deiner, aber das Grundprinzip ist das gleiche.

Wenn du willst kann ich dir deins auch mal zum funktionieren bringen, nur damit du die Unterschiede siehst :)
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

canlot
Beiträge: 393
Registriert: Di Mär 08, 2011 11:01 pm
Wohnort: NRW

Re: Problem mit Selectionsort

Beitrag von canlot » Mi Mär 09, 2011 8:24 am

Deiner Formulierung nach ist der Code nicht von dir. Ich würde dir bei einem so kurzem Code empfehlen zuerst genau nachzuvollziehen wie der Algorithmus funktioniert und ihn anschließend selbstständig zu implementieren.
DER CODE IST VON MIR. Ich hab denn selbst entworfen und keine anderen Sortalgorithmen angeguckt, weil ich selber was lernen will. Das Problem ist nur, dass das Programm mir nicht mehr gehorchen will. :lol:
Eigentlich wollte ich denn Algorithmus so schreiben: arr[a] soll sich mit arr vergleichen(bei meinen vorigen Code hab ich b=0 gesetzt), arr[a] soll immer um eins steigen und wenn es ein Wert gefunden hat, dann soll arr denn übernehmen und weiter vergleichen. Dadurch soll der letzte also der größte Wert dann in newar gespeichert werden. Der Wert temp speichert denn letzen größten Wert und stellt eine Bedingung dar damit man denn letzen größten Wert auslässt:

Code: Alles auswählen

if (arr[a] > arr[b] && arr[a] < temp)
Die Werte vergleichen damit sie nicht doppelt vorkommen hab ich gemacht hat aber bei mir nicht funktioniert.

Code: Alles auswählen

if(arr[b] == temp)
Vielen Dank!
zu mir :D
bin 18, programmieren seit einem Jahr C, vorher Visual Basic und "HTML", in der Schule programmieren wir mit C#.
Darf ich hier protzen und sagen das ich der beste in der Klasse bin? :D
Unwissenheit ist ein Segen

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Problem mit Selectionsort

Beitrag von Xin » Mi Mär 09, 2011 9:34 am

canlot hat geschrieben:bin 18, programmieren seit einem Jahr C, vorher Visual Basic und "HTML", in der Schule programmieren wir mit C#.
Darf ich hier protzen und sagen das ich der beste in der Klasse bin? :D
Sollte der Name Can-A-Lot heißen und Du hast das A vergeigt? ;-D

Willkommen im Forum. ^^
Sowas im Idealfall ins /Uservorstellung gerne gewürzt mit Hobbys, vollständigem Lebenslauf und der PIN Deiner EC-Karte. Besten Dank. ;-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Problem mit Selectionsort

Beitrag von Dirty Oerti » Mi Mär 09, 2011 12:49 pm

canlot hat geschrieben:DER CODE IST VON MIR. Ich hab denn selbst entworfen und keine anderen Sortalgorithmen angeguckt, weil ich selber was lernen will. Das Problem ist nur, dass das Programm mir nicht mehr gehorchen will. :lol:
Eigentlich wollte ich denn Algorithmus so schreiben: arr[a] soll sich mit arr[ b] vergleichen(bei meinen vorigen Code hab ich b=0 gesetzt), arr[a] soll immer um eins steigen und wenn es ein Wert gefunden hat, dann soll arr[ b] denn übernehmen und weiter vergleichen. Dadurch soll der letzte also der größte Wert dann in newar gespeichert werden. Der Wert temp speichert denn letzen größten Wert und stellt eine Bedingung dar damit man denn letzen größten Wert auslässt:
Also, nach dem ich gestern Abend ja angekündigt hab, dass ich das auch zurecht biegen kann, muss ich dir leider sagen, dass das SO nicht funktioniert.

Grund dafür ist folgender: (oben Eingabe, unten Ausgabe)
5 | 4 | 4 | 3
x | x | x | x

Du suchst zu erst den größten Wert, sprich die 5:

5 | 4 | 4 | 3
5 | x | x | x

Nun suchst du einen Wert, der kleiner als 5 ist und gleichzeitig der größte unter diesen in Frage kommenden Werten ist.
Dabei wirst du zwangsläufig auf die 4 kommen.

5 | 4 | 4 | 3
5 | 4 | x | x

So, und jetzt haben wir das Dilemma.
Mit deiner Methode (dem ECHT kleiner .. also < temp) wirst du nun einen Wert suchen, der kleiner als 4 ist.
Damit verlierst du die zweite 4 aus deiner Eingabe, du findest die 3

5 | 4 | 4 | 3
5 | 4 | 3 | x

Der letzte Wert würde bei deinem ursprünglichen Code mit Speichermüll gefüllt werden, arr[big] ja nicht definiert ist. (b kann sich nun nicht mehr ändern)

Wenn du anstatt dem ECHT kleiner ein KLEINER GLEICH benutzt hast du folgendes Problem:
Du findest den nächsten Wert, der KLEINER GLEICH 4 ist und auch am größten unter diesen: Das ist die 4.

5 | 4 | 4 | 3
5 | 4 | 4 | x

Jetzt suchst du wieder nach einem Wert KLEINE GLEICH 4 ... und voila, du findest wieder eine 4!

5 | 4 | 4 | 3
5 | 4 | 4 | 4

Und schon haben wir die 3 (bzw alles, was dahinter kommen würde) verloren!

Dieses Problem ist SO, mit deinem Algorithmus nicht lösbar!
Du müsstest dir höchstens merken, welche Wert aus der Eingabe du schon benutzt hast und dann nur unter denjenigen suchen, die noch nicht in der Ausgabe platziert wurden.

Hier ist mal, was ich daraus noch zusammengezaubert hab:

Code: Alles auswählen

#include <stdio.h>
#include <limits.h>

int main(int argc, char** argv)
{
  /*****************************************************************************
   * Eingabe - Feld, welches sortiert werden soll
  */
  const int SIZE = 10;
  int eingabe[SIZE];
  eingabe[0] = 345;
  eingabe[1] = 435;
  eingabe[2] = 16;
  eingabe[3] = 18;
  eingabe[4] = 17;
  eingabe[5] = 3070;
  eingabe[6] = 165;
  eingabe[7] = 453;
  eingabe[8] = 166;
  eingabe[9] = 300;
  
  
  /*****************************************************************************
   * Sortieren
  */
  // Platz fuer das fertig sortierte Feld, wir sortieren NICHT in situ!
  int ausgabe[SIZE];
  
  // Wo in ausgabe muessen wir als naechstes etwas ablegen?
  int platzier_iterator = 0;
  
  // Wir speichern uns, welchen Wert wir zuletzt in ausgabe geschrieben haben
  // und wo (Index) wir diesen Wert in eingabe (!!) gefunden hatten!
  // Fuer den ersten Durchgang brauchen wir einen Wert, der groesser ist, als
  // alles, was in eingabe steht. Also nehmen wir INT_MAX!
  int zuletzt_platziert_index = -1;
  int zuletzt_platziert_wert = INT_MAX;
  
  // Wir platzieren nach einander die Werte in ausgabe
  while (platzier_iterator < SIZE)
  {
    /* Zu erst suchen wir den Wert, welcher (ohne die schon platzierten Werte)
     * in eingabe am groessten ist!
    */
    
    // Wo suchen wir als naechstes in eingabe?
    int such_iterator = 0;
    
    // Wir speichern uns, welchen Wert wir schon gefunden haben, der unsere
    // Anforderungen erfuellen koennte. Wir speichern uns auch, wo wir diesen
    // Wert im eingabe gefunden haben.
    int gesucht_index = 0;
    int gesucht_wert = INT_MIN;
    
    // Die eigentliche Suche
    while (such_iterator < SIZE)
    {
      // Wir haben einen Wert, der kleiner/gleich als der zuletzt platzierte
      // Wert ist. Diese Ueberpruefung ist notwendig, um schon platzierte Werte
      // aus der Suche auszuschliessen!
      if (eingabe[such_iterator] <= zuletzt_platziert_wert)
      {
        // Nicht den zuletzt platzierten Wert nehmen, das ist ein Ansatz, der
        // manchmal Abhilfe schafft, aber eben nicht immer!!!
        if (such_iterator != zuletzt_platziert_index)
        {
          // Wir haben einen Wert gefunden, der groesser als unser bisheriger
          // Wert ist. Den merken wir uns!
          if (eingabe[such_iterator] > gesucht_wert)
          {
            // Wir merken uns den Wert und auch den Ort, an dem wir ihn gefunden
            // haben!
            gesucht_index = such_iterator;
            gesucht_wert = eingabe[such_iterator];
          }
        }
      }
      // Weitersuchen!
      such_iterator++;
    }
    
    
    /* Wir haben den gesuchten Wert gefunden und platzieren ihn nun an der
     * richtigen Stelle!
    */
    
    // Platzieren!
    ausgabe[platzier_iterator] = eingabe[gesucht_index];
    
    // Und wir muessen auch im naechsten Durchgang noch wissen, welchen Wert wir
    // hier gerade platziert haben! Und auch, von wo!
    zuletzt_platziert_wert = eingabe[gesucht_index];
    zuletzt_platziert_index = gesucht_index;
    
    // Weiter, um den naechsten Wert zu platzieren!
    platzier_iterator++;
  }
  
  
  /*****************************************************************************
   * Ausgabe des fertig sortierten Feldes
  */
  printf("(");
  int print_iterator = 0;
  while (print_iterator < SIZE)
  {
    printf(" %d ", ausgabe[print_iterator]);
    print_iterator++;
  }
  printf(")\n");
  return 0;
}
Problem ist wie gesagt, sobald gleiche Werte vorkommen zerlegt es das Programm.
Das liegt daran, dass der Algorithmus SO nicht funktioniert.

Hoffe du verstehst, wo das Problem liegt :)
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Problem mit Selectionsort

Beitrag von Kerli » Mi Mär 09, 2011 4:26 pm

canlot hat geschrieben:DER CODE IST VON MIR. Ich hab denn selbst entworfen und keine anderen Sortalgorithmen angeguckt, weil ich selber was lernen will. Das Problem ist nur, dass das Programm mir nicht mehr gehorchen will. :lol:
Ok, dann habe ich das wohl falsch verstanden. Aber vor allem der Kommentar
b ist ein komischer Wert, der anscheinend zum Teil nicht gebrauch wird
hat mich vermuten lassen, dass der Code von wo anders her sein könnte :P
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

canlot
Beiträge: 393
Registriert: Di Mär 08, 2011 11:01 pm
Wohnort: NRW

Re: Problem mit Selectionsort

Beitrag von canlot » Mi Mär 09, 2011 7:02 pm

Vielen Dank Dirty Oerti ich hab das Problem verstanden.
Ich werde demnächst den Code neu schreiben und dann posten wenn es funktioniert.
Kerli hat geschrieben:Ok, dann habe ich das wohl falsch verstanden. Aber vor allem der Kommentar
b ist ein komischer Wert, der anscheinend zum Teil nicht gebrauch wird
Ja weise dem b ein paar verschiedene Werte zu. Du wirst sehen das bei manchen das richtige und bei den anderen das falsche Ergebnis rauskommt.
Unwissenheit ist ein Segen

canlot
Beiträge: 393
Registriert: Di Mär 08, 2011 11:01 pm
Wohnort: NRW

Re: Problem mit Selectionsort

Beitrag von canlot » Mo Mär 14, 2011 1:19 pm

Hallo Zusammen :D
Habe mich 2 Stunden damit beschäftigt.
Hab auch geschafft.
Hier mein Code!!

Code: Alles auswählen

#include <stdio.h>

        int main(void)
        {
            int counter = 0; // Äußerer Zähler
            const int value = 10; // feste Arraygröße
            int arr[value]; // ungeordnetes Array
            int newarr[value]; // geordnetes Array

            int fast = 0; // innerer Durchlauf - also schneller
            int low = 0; // zugewiesener Wert - langsamer
            int temp = 0; // Zwischenzähler für newarr

            arr[0] = 345;
            arr[1] = 300;
            arr[2] = 300;
            arr[3] = 4556;
            arr[4] = 165;
            arr[5] = 3070;
            arr[6] = 453;
            arr[7] = 3070;
            arr[8] = 166;
            arr[9] = 300;

                while(counter < value)
                {
                        fast = counter; // Die Variablen "fast" und "low" lassen denn letzten
                        low = counter;  // größten Wert aus.
                        while(fast < value)
                        {
                            if(arr[fast] >= arr[low])
                            {
                                low = fast; // "low" wird der Wert vom "fast" zugewiesen
                            }
                            fast++;
                        }
                        newarr[temp] = arr[low];
                        arr[low] = arr[counter]; // Der Wert von Anfang nimmt den Platz vom größten Arraywert ein
                        temp++;
                        counter++;
                }

            counter = 0;
            while(counter < value)
            {
            printf("%d\n",newarr[counter]);
            counter++;
            }
            return 0;
        }
Das Grundprinzip ist, wenn man vergleicht und denn größten Wert hat, speichert man denn und dann mit denn ersten Wert vertauscht(bildlich gesehen).
Da ein Wert nicht mehr vorhandeln ist geht der counter ein weiter und fängt bei denn zweiten Wert an u.s.w. .
Wie findet ihr es?
Habt ihr Optimierungsvorschläge?
Unwissenheit ist ein Segen

Antworten