Teilnehmerliste erstellen mit Sortierung



  • Hmm @Fellhuhn: Korintenkackerei nennt sich das ... dann caste halt! Ist in dem Fall i.o. ...



  • Die Meldung besagt das du auf einen Bereich des Strings zugegriffen hast, die nicht definiert ist. Also zum Beispiel auf die siebte Stelle eines Strings mit nur drei Zeichen.

    Du hast da auch noch nachname[i][j]=tolower(vorname[i][j]); stehen. Sollte am Ende wohl auch nachname heißen.



  • Tja, auch "Veteranen" passieren gelegentlich Tipfehler - das muß natürlich "j<vorname[i].length()" heißen, sonst bekommst du eine Endlosschleife - und letztlich deinen SegFault.



  • GEIL DAnke. 2/3 sind nun geschafft von dem Programm. Jeztt fehlt "nur" noch die Sortierung nach Nachnamen. Wird wohl wieder in ner For schleife gemacht oder?



  • (D)Evil schrieb:

    Hmm @Fellhuhn: Korintenkackerei nennt sich das ... dann caste halt! Ist in dem Fall i.o. ...

    Wie willst du in dem Fall casten ohne eine Funktion dazwischenzuschieben oder es noch schwieriger zu verstehen machen indem du Funktionspointer castest? Wenn du Neulingen das empfiehlst dann wäre es gut wenn es auch funktioniert, sonst setzt die komplette Frustration ein. 😉



  • Eine einfache for-Schleife wird dafür wohl nicht ausreichen, aber schau dich mal im Netz nach brauchbaren Sortier-Algorithmen um (BubbleSort, InsertSort - oder auch QuickSort).

    PS: Ich hätte ja lieber EIN Array mit struct's verwendet und einmal durch std::sort() gejagt, aber das steht bei der Aufgabenstellung nicht zur Debatte.



  • Also es erste was ich jetzt denke ich machen würde ist die Vornamen,nachnamen und Nummer miteinander zu verketten. Müsste mit dem getline() gehen oder? Aber dann ist halt doof. Mal überlegen?!?! Habt ihr Tipss??



  • Überleg dir erst einmal wie du das machen würdest.

    Vermutlich indem du dir von vorne an jedes Element des Nachnamen-Arrays anschaust und guckst ob es "kleiner" als das vorherige ist. Ist das der Fall vertauscht du die beiden und auch die beiden Einträge im Vornamen- und Matrikelnummer-Array. Dann gehst du wieder einen Schritt zurück und schaust von da an.



  • Fellhuhn schrieb:

    Überleg dir erst einmal wie du das machen würdest.

    Vermutlich indem du dir von vorne an jedes Element des Nachnamen-Arrays anschaust und guckst ob es "kleiner" als das vorherige ist. Ist das der Fall vertauscht du die beiden und auch die beiden Einträge im Vornamen- und Matrikelnummer-Array. Dann gehst du wieder einen Schritt zurück und schaust von da an.

    Das hört sich aber einfach an:) Verwirklichen lassen wirds dann schon "bissl" schwerer. Ich überlege gerade!!



  • Verketten ist gut - getline() ist hierfür aber Unsinn.

    Ich hätte es so gelöst:

    struct eintrag
    {
      string vorname,nachname;
      int nummer;
    };
    
    bool operator<(const eintrag& r,const eintrag& l)
    {
      return r.nachname<l.nachname;
    }
    
    int main()
    {
      eintrag liste[1000];
    
      ...//Namen in die Liste einlesen (statt 'vorname[i]' verwendest du 'liste[i].vorname'
    
      sort(liste,liste+n);
    }
    

    (oder noch besser - gleich einen sortierenden Container (set<>/multiset<>) zum Speichern der Datensätze verwenden)

    Wenn die Aufgabe wirklich vorschreibt, drei Arrays zu verwenden, mußt du selber ein Sortierverfahren umsetzen - und dabei alle drei Arrays simultan sortieren:

    ...
      if(nachname[i]>nachname[j])
      {
        swap(vorname[i],vorname[j]);
        swap(nachname[i],nachname[j]);
        swap(nummer[i],nummer[j]));
      }
    


  • Hmm es Problem ist nur, dass ich ja nur was programmieren kann, was ich auch verstehe.:) Ausserdem haben wir das ja noch nicht im Script durchgearbeitet, weiß auch gar nicht ob da sowas drin steht. Gibts denn da keine andere Lösung?

    was ist denn sie swap funktion??

    so vom denkansatz habe ich erst mal gedacht
    if
    nachname[i]<nachname[i+1]
    hmm ja und dann gehts auch schon los



  • wog schrieb:

    Hmm es Problem ist nur, dass ich ja nur was programmieren kann, was ich auch verstehe.:) Ausserdem haben wir das ja noch nicht im Script durchgearbeitet, weiß auch gar nicht ob da sowas drin steht. Gibts denn da keine andere Lösung?

    Es gibt mehr als genug Sortier-Algorithmen (schau mal in die Wikipedia) - du mußt dir nur einen aussuchen und umsetzen.

    (aber wenn in euren Aufgaben verlangt wird, daß ihr sortiert, müsstet ihr doch auch schon irgendeine Funktion dafür kennengelernt haben)

    was ist denn sie swap funktion??

    Die swap() Funktion vertauscht zwei Werte miteinander - wenn sie dir nicht gefällt, kannst du auch den klassischen Dreieckstausch durchführen (string vntemp=vorname[i];vorname[i]=vorname[j];vorname[j]=vntemp;).

    so vom denkansatz habe ich erst mal gedacht
    if
    nachname[i]<nachname[i+1]
    hmm ja und dann gehts auch schon los

    Ja, der Ansatz ist schonmal gut - jetzt mußt du nur noch diesen Vergleich für alle Kombinationen von i und 1 *sic* durchführen.



  • So in etwa.
    swap ist eine weitere Funktion der STL. Tauscht stumpf zwei Elemente aus. Das kann man natürlich auch manuell über eine temporäre lokale Variable machen, ist aber nicht halb so "elegant".

    for(int i = 1; i < n; i++){
    	if (i == 0) continue; 
    	if (nachname[i] < nachname[i-1]){
    	    swap(nachname[i], nachname[i-1]);
    	    swap(vorname[i], vorname[i-1]);
                swap(matrikelnummer[i], matrikelnummer[i-1]);
    	    i-=2;
    	}
        }
    


  • ...
      if(nachname[i]>nachname[j])
      {
        swap(vorname[i],vorname[j]);
        swap(nachname[i],nachname[j]);
        swap(nummer[i],nummer[j]));
      }
    

    Hab ich das richtig verstanden? Wenn also jetzt der nachname[i] größer wie nachname von [j] ist dann tauschen die 2 nachnamen automatisch den platz und es nimmt auch gleich meinen vornamen und nummer mit?

    das wäre ja schon die lösung!! müsste man nur noch abklären, wie das läuft. vermutlich in ner for schleife von 0-??

    p.s dann könnte ich doch j auch als i+1 schreiben oder??



  • Es gibt natürlich unterschiedliche Ansätze wie du die Vergleiche anstellst.

    Du kannst es wie in meinem Beispiel machen und benachbarte Elemente immer miteinander vergleichen und die Elemente so "durchreichen". Der zeitliche Aufwand ist allerdings nicht besonders gering. Relativ zumindest.

    Oder du vergleichst das Element an Position x immer mit allen Elementen die an den Positionen > x stehen und tauscht die jeweils aus, wenn sie geringer sind. Geht alles.

    Gibt auch noch viel komplexere aber schnellere Methoden, hattet ihr denn keine in der Vorlesung?



  • In einer einfachen for()-Schleife kommst du da nicht weit (durch das Vertauschen kann es passieren, daß das i-te Element nicht mehr zu seinem Vorgänger passt) - die meisten Sortieralgorithmen verwenden zumindest doppelt verschachtelte Schleifen oder sogar noch kompliziertere Zuordnungen, um zu bestimmen, welche Werte sie vergleichen und austauschen müssen.

    (nein, ich werde hier nicht alle bekannten Verfahren ausbreiten - ich verweise nur (zum wiederholten Mal) auf die Wikipedia)



  • Eine einfache Schleife funktioniert. Man muss nur entsprechend weit zurückgehen. So das man das zurückgeschobene Element wieder mit dem davor vergleicht. Wie in meinem Beispiel oben.
    Mit zwei Schleifen geht es natürlich auch.
    Andere Daten, gleiche Sache:

    for(int i = 0; i < 3; i++){
    	for(int j = i+1; j < 4; j++){
    	    if (te[i] < te[j]){
    		swap(te[i], te[j]);
    		swap(kn[i], kn[j]);
    	    }
    	}
        }
    


  • Fellhuhn schrieb:

    Du kannst es wie in meinem Beispiel machen und benachbarte Elemente immer miteinander vergleichen und die Elemente so "durchreichen". Der zeitliche Aufwand ist allerdings nicht besonders gering. Relativ zumindest.

    Für dies Methode habe ich mich entschieden des war ja des mit dem Swap und so. Nein hatten leider nix in der Vorlesung oder zumindest nicht woran ich mich erinnern kann und ich war in jeder Vorlesung bisher da

    Komm aber nit so weiter:

    if(nachname[i]>nachname[j])
      {
        swap(vorname[i],vorname[j]);
        swap(nachname[i],nachname[j]);
        swap(nummer[i],nummer[j]);
      }
    for(int i=0;i<n;i++)
    {cout<<nachname[i]<<vorname[i]<<nummer[i]<<endl;
    }
    }
    


  • Fellhuhn schrieb:

    Eine einfache Schleife funktioniert. Man muss nur entsprechend weit zurückgehen. So das man das zurückgeschobene Element wieder mit dem davor vergleicht. Wie in meinem Beispiel oben.
    Mit zwei Schleifen geht es natürlich auch.
    Andere Daten, gleiche Sache:

    for(int i = 0; i < 3; i++){
    	for(int j = i+1; j < 4; j++){
    	    if (te[i] < te[j]){
    		swap(te[i], te[j]);
    		swap(kn[i], kn[j]);
    	    }
    	}
        }
    

    Ist da die 3 und 4 entscheident oder was bedeutet das denn?



  • In dem Beispiel habe ich andere Daten verwendet. 3 wäre hier n-1 und 4 wäre n. te wäre nachname, kn vorname und für die Matrikelnummern bräuchtest du eine extra Zeile.


Anmelden zum Antworten