Überprüfen ob vektor sortiert ist und dabei ein Template benutzen



  • Noch mal zurück zu isSorted :
    Du brauchst in der Funktion nur die Zählvariable für die Schleife, die übrigen Informationen stecken alle im Vektor. Du benutzt als Zählvariable x und y , wobei y immer 1 größer ist als x . Es reicht also aus, wenn du nur eine Zählvariable benutzt und zum Vergleichen von zwei Elementen deren Wert um 1 erhöhst oder verringerst.

    // Variante 1:
    for( size_t i = 0; i < v.size() -1; ++i )
    {
       // Vergleiche Elemente an Position i und i +1
    }
    
    // Variante 2:
    for( size_t i = 1; i < v.size(); ++i )
    {
       // Vergleiche Elemente an Position i-1 und i
    }
    

    Variante 1 hat Variante 2 gegenüber einen Nachteil, es muss der Sonderfall für Vektoren der Länge 1 oder weniger behandelt werden, da i +1 sonst auf ungültige Elemente zugreift.

    Außerdem braucht du die Information, wie viele Elemente sortiert sind, nicht. Sobald von zwei aufeinanderfolgenden Elementen das erste größer als das zweite ist weißt du schon, dass der Vektor nicht sortiert ist und kannst false zurückgeben.

    if( v[i] > v[i +1] ) return false;
    

    Damit kannst du deine Funktion auf maximal 5 Zeilen reduzieren, selbst wenn du großzügig Code auf mehrere Zeilen verteilst.



  • @ Einzeller
    Ja, klar.

    Ich bin allerdings der Meinung dass es für Lernende oft besser ist wenn man Stück für Stück vorgeht. Also erstmal alles was schlecht/verbesserungswürdig ist anspricht und "korrigiert", auch wenn es Dinge sind die in der "optimalen" Lösung überhaupt nicht mehr vorkommen. Und den Code den sie zeigen Schritt für Schritt in die "optimale" Lösung verwaldelt und jeden Schritt erklärt.

    Natürlich ist das sehr mühsam, und ich beschränke mich meist darauf ein oder maximal zwei solche Schritte pro Posting aufzuzeigen. Wenn der Lernende dann die Geduld verliert oder ich vergesse den Thread weiter zu verfolgen, dann hat er am Ende natürlich nicht die optimale Lösung. Aber er hat vermutlich (hoffentlich) mehr dabei gelernt als wenn man ihm die fertige optimale Lösung hinschreibt.



  • hi,
    ich hab nun so manches abgeändert/verbessert:

    #include<iostream>
    #include<vector>
    
    using namespace std;
    
    template<typename T>
    
    bool isSorted(const vector<T> &v)
    {
        for(size_t i=1; i<v.size(); ++i)
        {
            if(v[i] >= v[i-1]);
            else return false;
        }
        return true;
    }
    
    template<typename T>
    
    double getAverage(const vector<T> &v)
    {
        double summe = 0;
        for(size_t i=0; i<v.size(); ++i)
        {
            summe+=v[i];
        }
        return summe/v.size();
    }
    
    int main()
    {
        cout<<"Geben an, ob die Reihenfolge des vektors auf int, double oder chars geprüft werden soll! (i, d oder c eingeben)\n"; 
        char pruefung; 
        cin>>pruefung; 
        int i, anzahl_werte;
        switch(pruefung) 
        { 
            case 'i': 
            {
                cout<<"Wie viele ints sollen in den vektor geschrieben werden?\n";
                cin>>anzahl_werte;
                cout<<"Gebe nun "<<anzahl_werte<<" ints ein:\n";
                vector<int> a; 
                int ganzzahl;
                for(i=0; i<anzahl_werte; ++i)
                {
                    cin>>ganzzahl;
                    a.push_back(ganzzahl);
                }
                if(isSorted(a))
                    cout<<"Die angegebenen ints sind in aufsteigender reihenfolge sortiert!\n";
                else
                    cout<<"Die angegebenen ints sind NICHT in aufsteigender reihenfolge sortiert!\n";
                cout<<"Der durchschnitt der im vektor eingetragenen werte betraegt: "<<getAverage(a)<<'\n';
                break; 
            } 
            case 'd': 
            {
                cout<<"Wie viele doubles sollen in den vektor geschrieben werden?\n";
                cin>>anzahl_werte;
                cout<<"Gebe nun "<<anzahl_werte<<" doubles ein:\n";
                vector<double> b; 
                double kommazahl;
                for(i=0; i<anzahl_werte; ++i)
                {
                    cin>>kommazahl;
                    b.push_back(kommazahl);
                }
                if(isSorted(b))
                    cout<<"Die angegebenen doubles sind in aufsteigender reihenfolge sortiert!\n";
                else
                    cout<<"Die angegebenen doubles sind NICHT in aufsteigender reihenfolge sortiert!\n";
                cout<<"Der durchschnitt der im vektor eingetragenen werte betraegt: "<<getAverage(b)<<'\n';
                break; 
            } 
            case 'c': 
            {
                cout<<"Wie viele chars sollen in den vektor geschrieben werden?\n";
                cin>>anzahl_werte;
                cout<<"Gebe nun "<<anzahl_werte<<" chars ein:\n";
                vector<int> c; 
                char zeichen;
                for(i=0; i<anzahl_werte; ++i)
                {
                    cin>>zeichen;
                    c.push_back(zeichen);
                }
                if(isSorted(c))
                    cout<<"Die angegebenen chars sind in aufsteigender reihenfolge sortiert!\n";
                else
                    cout<<"Die angegebenen chars sind NICHT in aufsteigender reihenfolge sortiert!\n";
                cout<<"Der durchschnitt der im vektor eingetragenen werte betraegt: "<<getAverage(c)<<'\n';
                break; 
            } 
            default: 
            { 
                cout<<"Fehler! i, d oder c eingeben (i=int ; d=double ; c=char)!\n"; 
            } 
        } 
        return 0; 
    }
    

    getaverage hab ich etwas verändert, damit der mir auch bei ints ein genaues ergebnis liefert.

    summe=summe-summe hatte ich geschrieben weil ich gedacht hab 0 könnte ich nicht in ein double schreiben (sondern müsste 0.0 schreiben was bei int dann rumspackt). Ist aber wohl nicht so.

    Das

    X summe = X(), durschnitt;
    

    und das mit dem adjazent haben wir noch nich. Bin mir nicht so sicher ob wir sachen benutzen dürfen die wir noch nicht hatten.

    Achja das mit den warnungen ist so ein problem bei mir... Ich benutze netbeans mit cygwin und irgendwie gibt der keine warnungen aus beim kompilieren. Bei dem compile befehl den man unten in der box sieht, schreibt der auch nirgendwo den paramter "-w". Hatte deswegen schonmal gegoogelt, bin aber nicht drauf gekommen wie man das bei netbeans einstellt, falls es überhaupt geht. finde auch in den einstellungen dazu nichts.



  • vivess schrieb:

    hi,
    ich hab nun so manches abgeändert/verbessert:

    template<typename T>
    bool isSorted(const vector<T> &v)
    {
        for(size_t i=1; i<v.size(); ++i)
        {
            if(v[i] >= v[i-1]);
            else return false;
    

    Hui, das ist aber mal ein "interessantes" if...
    Wenn ein Element größergleich seinem Vorgänger ist, dann mache nichts. Sonst return false. Dinge wie "nichts machen" sind irgendwie überflüssig. Du kannst einfach nach dem Gegenteil fragen: Wenn ein Element nicht größergleich seinem Vorgänger ist, return false. Und nicht gößergleich bedeutet kleiner. Also:

    if (v[i] < v[i-1]) return false;
    

    Das

    X summe = X(), durschnitt;
    

    und das mit dem adjazent haben wir noch nich. Bin mir nicht so sicher ob wir sachen benutzen dürfen die wir noch nicht hatten.

    X() ist hier einfach der default-Konstruktor des Typs X.
    Bzgl. std::adjacent_find fürchte ich, dass du dir das selbst aneignen musst. Wer weiß, ob dein Lehrer den algorithm-Header gut kennt bzw. genügend Zeit ist, alle Algorithmen zu lehren. Daher: schau in den üblichen Quellen nach. Also z.B. hier: http://en.cppreference.com/w/cpp/algorithm/adjacent_find - und lies mal das Beispiel durch, es löst enthält nämlich ein isSorted 🙂


Anmelden zum Antworten