Sortiertemplate (spezifisch für strings)



  • schonmal danke für deine antworten 🙂

    ich schaue mir mal die tutorials an!
    Leider darf ich keine schon "vorgefertigten" algorithemen oder systembefehle benutzen, sondern muss alles selbst coden 😞


  • Mod

    newling987 schrieb:

    Leider darf ich keine schon "vorgefertigten" algorithemen oder systembefehle benutzen, sondern muss alles selbst coden 😞

    Und die Sachen aus den Headern string und iostream zählen nicht dazu?



  • newling987 schrieb:

    schonmal danke für deine antworten 🙂

    ich schaue mir mal die tutorials an!
    Leider darf ich keine schon "vorgefertigten" algorithemen oder systembefehle benutzen, sondern muss alles selbst coden 😞

    ach so... jop...
    die sind ja nicht "vorgefertigt" sondern werden so benutzt, vom reinen vorgehen... 🙂 -> das "feste" prinzip ist ja gerade deren stärke...
    anpassen musst du eh... 😃 -> aufsteigend, absteigend 😃

    ptr hat wahrscheinlich den falschen datentyp... (bzw. zeigt auf den falschen, vll kannst das ja mal eben testen... hab gerade keine ide zur verfügung... ist für mich halt relativ schwierig weil der code ist ohne die tags schlecht zu lesen...)
    aber so wie ich das sehe zeigt wahrscheinlich ptr auf einen falschen datentyp... (evt. std::string?) -> zumindest laut fehlermeldung...
    und wenn ptr ein string ist dann gibts kein "ptr->next"...



  • also ich hab nochmal geschaut...
    weiß nicht genau ob es dieses "ptr-next" wirklich gibt? was soll das sein? eine funktion? ich dachte "next" spring automatisch weiter ... aber i.wie find ich diese funktion nicht... (bzw. bei mir gibts die nicht...)
    das wird dann auch der fehler sein... vll hilft dir das hier...:
    hab das eben gecodet um es zu verdeutlichen...

    #include <iostream>
    #include <string>
    
    int main()
    {
    	struct test
    	{
    	   int test_int_1;
    	   int test_int_2;
    	   int test_int_3;
    	   int test_int_4;
    	   int test_int_5;
    
    	   int array[10]={1,2,3,4,5,6,7,8,9,10};
    	};
    
    	//hier wird die stuktur angelegt und ein pointer auf die werte von "struktur" gesetzt
    	struct test struktur;
    	struct test *ptr = &struktur;
    
    	//werte über den pointer zuweisen
    	ptr->test_int_1 = 5;
    	ptr->test_int_2 = 10;
    	ptr->test_int_5 = 1000000000;
    
    	//hier testen obs geklappt hat... (über pointer den wert abfragen)
    	std::cout <<"1: " << ptr-> test_int_1 << std::endl;
    	std::cout <<"2: " << ptr-> test_int_2 << std::endl;
    	std::cout <<"5: " << ptr-> test_int_5 << std::endl;
    
    	//---------------------------------------------------------------------
    
    	int gr=0;
    	int x=0;
    
    	//hier wird die größe des arrays festgestellt
    	gr=sizeof(ptr->array)/sizeof(int);
    
    	while(x!=gr)
    	{
    		std::cout << ptr->array[x] << std::endl;
    		x++;
    	}
    
    }
    

    also du musst den pointer erst einen wert/bzw. adresse geben... sonst ist "next" kein element von ptr... 😉 wie in der fehler meldung...

    schau oben in mein beispiel da siehst du wie man ptr sofern du es so nennen willst werte gibt 😉 ...

    wenn du das machst sollte der fehler behoben sein 😉 ...

    lg
    hoff das hat dir geholfen...
    sry das es kruz gedauert hat... 🙂



  • so hab das programm jetzt soweit verändert, dass es startet 🙂
    leider werden keine benutzereingabe oder so eingelesen...
    liegt es am programm? (hauptprogramm?)

    also mit vorgefertigt mein ich sowas wie (das gehört jetzt zwar nicht zu DIESEM thema), aber sachen wie, dass automatisch alle buchstaben eines strings in groß oder in kleinbuchstaben umgewandelt werden!
    ___________________________________________________________________________
    Hauptprogramm:
    [code="cpp"]#include <iostream>
    #include <string>

    using namespace std;

    #include "Template.h"
    #include "sortierfunktion.h"

    int main(int argc, char* argv[])

    { TListenKnoten<string> *anker = nullptr;

    for (int i = 1; i < argc; i++)
    hinten_anfuegen<string>(anker, argv[i]);

    if (string(argv[0]) == "auf.exe")
    sortiere<TListenKnoten<string>, string>(anker,&aufsteigend<string>); //Aufruf der Sortierfunktion (aufsteigende Sortierung)

    else if (string(argv[0]) == "ab.exe")
    sortiere<TListenKnoten<string>, string>(anker, //Aufruf der Sortierfunktion (absteigende Sortierung)
    &absteigend<string>);

    else
    {
    std::system("PAUSE"); return 1;
    }

    liste_ausgeben<string>(anker);

    std::system("PAUSE");
    return 0;
    }
    _______________________________________________________________________________
    sortierfunktion:

    #include "Template.h"
    #include <string>

    using namespace std;

    template <typename T> void aufsteigend(T &x, T &y) {

    if (x > y) {
    T temp = x;
    x = y;
    y = temp;
    }

    }
    template void aufsteigend<string>(string &x, string &y);

    template <typename T> void absteigend(T &x, T &y)
    {

    if (x < y) {
    T temp = x;
    x = y;
    y = temp;
    }

    }
    template void absteigend<string>(string &x, string &y);

    template <typename T1, typename T2>
    void sortiere(T1 *anker,
    void(*cmp_p)(T2 &, T2 &))
    {
    T1 *ptr = anker;

    int anzahl_an_strings = 1;
    while (ptr->next != nullptr) //bis zum ende der liste (next-pointer des letzten elements entspricht dem nullpointer)
    {
    anzahl_an_strings++;
    ptr = ptr->next; //es wird durch die Liste gelaufen
    }

    ptr = anker; //Pointer wird wieder auf Anfang der Liste gesetzt

    for (int i = 0; i < anzahl_an_strings; i++) //i=Vergleichsrunden
    {
    cmp_p(ptr->data, ptr->next->data); //Sortierfunktion wird aufgerufen: es wird zwischen dem jetztigen Element
    ptr = ptr->next; //(auf welches der Pointer zeigt) und dem darauffolgendem (->next) verglichen
    }

    }
    template void sortiere<TListenKnoten<string>, string>(TListenKnoten<string> *anker,void(*cmp_p)(string &, string &));

    _______________________________________________________________________________
    Ausgeben und erstellen der Liste (Template.h):

    #pragma once

    template <typename T> struct TListenKnoten
    {
    T data;
    TListenKnoten<T> *next;
    };

    template <typename T> void hinten_anfuegen(TListenKnoten<T>* &anker, T wert)
    {

    TListenKnoten<T> *neuer_eintrag = new TListenKnoten<T>;
    neuer_eintrag->data = wert;
    neuer_eintrag->next = 0;

    if (anker == nullptr)
    anker = neuer_eintrag;

    else
    {
    TListenKnoten<T> *ptr = anker;

    while (ptr->next != nullptr)
    ptr = ptr->next;
    ptr->next = neuer_eintrag;
    }
    }

    template void hinten_anfuegen<string>(TListenKnoten<string> * &anker, string wert); //Instanziierung (für string)

    template <typename T> void liste_ausgeben(TListenKnoten<T> *anker)

    { if (anker == nullptr)
    cout << "Leere Liste." << endl;

    else
    {
    cout << "[ ";

    TListenKnoten<T> *ptr = anker;

    do
    {
    cout << ptr->data;
    if (ptr->next != nullptr) cout << " , ";
    else cout << " ";
    ptr = ptr->next;
    } while (ptr != nullptr);
    cout << "]" << endl;
    }
    }

    template void liste_ausgeben<string>(TListenKnoten<string> *anker);



  • sorry dass es wieder in getippter form ist!
    Ist mein erster beitrag überhaupt hier und sonst in nem c++-forum und weiß nicht genau wies geht 🤡



  • so hab das programm jetzt soweit verändert, dass es startet 🙂
    leider werden keine benutzereingabe oder so eingelesen...
    liegt es am programm? (hauptprogramm?)

    also mit vorgefertigt mein ich sowas wie (das gehört jetzt zwar nicht zu DIESEM thema), aber sachen wie, dass automatisch alle buchstaben eines strings in groß oder in kleinbuchstaben umgewandelt werden!

    👍
    also war das problem das es kein "next" gab?

    zu den benutzereingaben:
    hier ist das interessant:

    int main(int argc, char* argv[])
    

    das sind startparameter deines programms...
    worüber du die nutzereingaben tätigen kannst... (argc = wie viele argumente, argv = welche...)
    also starte dein prog. mal von der konsole/terminal/cmd was auch immer 😃 ...
    mit den richtigen eingaben... also

    (unter windows:)

    programm.exe EINGABE
    

    da musst du nur schauen was du angeben musst und in welcher reihenfolge...
    oder hattest das so gemacht und trozdem wurden keine "nutzereingaben erkannt?"


  • Mod

    newling987 schrieb:

    sorry dass es wieder in getippter form ist!
    Ist mein erster beitrag überhaupt hier und sonst in nem c++-forum und weiß nicht genau wies geht 🤡

    Die Smileys scheinst du doch gefunden zu haben? Guckst du mal etwas tiefer darunter, der Knopf mit "C++" drauf. Drei Methoden:

    • Quelltext markieren, Knopf drücken
    • Cursor an den Anfang des Quelltextes setzen, Knopf einmal drücken. Knopf bekommt ein Sternchen. Cursor ans Ende des Quelltextes setzten, Knopf noch einmal drücken.
    • Von Hand, ganz ohne Knopf [code="cpp"] an den Anfang des Quelltextes schreiben, und [/code] ans Ende.

    Als registrierter Nutzer kannst du deine Beiträge auch nachträglich editieren. Ich schlage vor, dass du dies tun solltest und die passenden Codetags einfügst. Mit der Vorschau kannst du sehen, ob es funktioniert.



  • nee ich hab das template in dem next definiert war nicht inkludiert und auch nicht string!

    ok alles klar dankeschön 🙂

    //Hauptprogramm: 
    #include <iostream> 
    #include <string> 
    
    using namespace std; 
    
    #include "Template.h" 
    #include "sortierfunktion.h" 
    
    int main(int argc, char* argv[]) 
    
    { TListenKnoten<string> *anker = nullptr; 
    
    for (int i = 1; i < argc; i++) 
    hinten_anfuegen<string>(anker, argv[i]); 
    
    if (string(argv[0]) == "auf.exe") 
    sortiere<TListenKnoten<string>, string>(anker,&aufsteigend<string>); //Aufruf der Sortierfunktion (aufsteigende Sortierung) 
    
    else if (string(argv[0]) == "ab.exe") 
    sortiere<TListenKnoten<string>, string>(anker, //Aufruf der Sortierfunktion (absteigende Sortierung) 
    &absteigend<string>); 
    
    else 
    { 
    std::system("PAUSE"); return 1; 
    } 
    
    liste_ausgeben<string>(anker); 
    
    std::system("PAUSE"); 
    return 0; 
    } 
    //_______________________________________________________________________________ 
    //sortierfunktion: 
    
    #include "Template.h" 
    #include <string> 
    
    using namespace std; 
    
    template <typename T> void aufsteigend(T &x, T &y) { 
    
    if (x > y) { 
    T temp = x; 
    x = y; 
    y = temp; 
    } 
    
    } 
    template void aufsteigend<string>(string &x, string &y); 
    
    template <typename T> void absteigend(T &x, T &y) 
    { 
    
    if (x < y) { 
    T temp = x; 
    x = y; 
    y = temp; 
    } 
    
    } 
    template void absteigend<string>(string &x, string &y); 
    
    template <typename T1, typename T2> 
    void sortiere(T1 *anker, 
    void(*cmp_p)(T2 &, T2 &)) 
    { 
    T1 *ptr = anker; 
    
    int anzahl_an_strings = 1; 
    while (ptr->next != nullptr) //bis zum ende der liste (next-pointer des letzten elements entspricht dem nullpointer) 
    { 
    anzahl_an_strings++; 
    ptr = ptr->next; //es wird durch die Liste gelaufen 
    } 
    
    ptr = anker; //Pointer wird wieder auf Anfang der Liste gesetzt 
    
    for (int i = 0; i < anzahl_an_strings; i++) //i=Vergleichsrunden 
    { 
    cmp_p(ptr->data, ptr->next->data); //Sortierfunktion wird aufgerufen: es wird zwischen dem jetztigen Element 
    ptr = ptr->next;	//(auf welches der Pointer zeigt) und dem darauffolgendem (->next) verglichen 
    } 
    
    } 
    template void sortiere<TListenKnoten<string>, string>(TListenKnoten<string> *anker,void(*cmp_p)(string &, string &)); 
    
    //_______________________________________________________________________________ 
    //Ausgeben und erstellen der Liste (Template.h): 
    
    #pragma once 
    
    template <typename T> struct TListenKnoten 
    { 
    T data; 
    TListenKnoten<T> *next; 
    }; 
    
    template <typename T> void hinten_anfuegen(TListenKnoten<T>* &anker, T wert) 
    { 
    
    TListenKnoten<T> *neuer_eintrag = new TListenKnoten<T>; 
    neuer_eintrag->data = wert; 
    neuer_eintrag->next = 0; 
    
    if (anker == nullptr) 
    anker = neuer_eintrag; 
    
    else 
    { 
    TListenKnoten<T> *ptr = anker; 
    
    while (ptr->next != nullptr) 
    ptr = ptr->next; 
    ptr->next = neuer_eintrag; 
    } 
    } 
    
    template void hinten_anfuegen<string>(TListenKnoten<string> * &anker, string wert); //Instanziierung (für string) 
    
    template <typename T> void liste_ausgeben(TListenKnoten<T> *anker) 
    
    {	if (anker == nullptr) 
    cout << "Leere Liste." << endl; 
    
    else 
    { 
    cout << "[ "; 
    
    TListenKnoten<T> *ptr = anker; 
    
    do 
    { 
    cout << ptr->data; 
    if (ptr->next != nullptr) cout << " , "; 
    else cout << " "; 
    ptr = ptr->next; 
    } while (ptr != nullptr); 
    cout << "]" << endl; 
    } 
    } 
    
    template void liste_ausgeben<string>(TListenKnoten<string> *anker);
    


  • gut freut mich wenn ich helfen konnte... 🙂
    viel erfolg noch 😃
    lg



  • Du brauchst Deine Templates nicht überall zu instanziieren. Alles rausschmeissen. Z.B. in template.h :

    template void liste_ausgeben<string>(TListenKnoten<string> *anker);
    

    Dann grübel nochmal über den Kern Deiner Anwendung: das sortieren.
    Warum ermittelst Du erst die Anzahl? könntest Du diesen Schritt nicht komplett einsparen?
    Mit dem Algorithmus scheinst Du etwas kurz zu springen.
    Welchen Algorithmus hast Du überhaupt im Kopf? Ist das auch der Algorithmus, den Du implementiert hast?

    template <typename T1, typename T2>
    void sortiere(T1 *anker, void(*cmp_p)(T2 &, T2 &))
    {
      T1 *ptr = anker;
    
      int anzahl_an_strings = 1;
      while (ptr->next != nullptr)
      {
        anzahl_an_strings++;
        ptr = ptr->next;
      } 
      ptr = anker;
      for (int i = 0; i < anzahl_an_strings; i++)
      {
        cmp_p(ptr->data, ptr->next->data);
        ptr = ptr->next;
      }
    }
    

Anmelden zum Antworten