C++ Verständnis eines Programms



  • Warum so kompliziert?

    Der einfache 2-Zeiler ist so:

    vector<int> zahlen = {13,42,13,23,11,5,42 };
    auto nunique_zahlen = size(set(begin(zahlen), end(zahlen)));
    


  • Ich biete eine 😉

    std::size_t count = std::set<int>{ 13, 42, 13, 23, 11, 5, 42 }.size();
    


  • @wob sagte in C++ Verständnis eines Programms:

    Warum so kompliziert?

    Ich wollte ihm eine Lösung mittels STL zeigen, welche eine gewisse Ähnlichkeit mit seinem Code hat. Aber natürlich ist dein Code besser.

    Und noch eine mögliche Lösung:

    #include <vector>
    #include <algorithm>
    #include <iostream>
    #include <set>
    
    
    int main()
    {
      std::vector<int> Numbers { 13, 42, 13, 23, 11, 5, 42 };
    		
      std::sort(std::begin(Numbers), std::end(Numbers));
      std::cout << "Anzahl der verschiedenen Zahlen: " <<
        std::distance(std::begin(Numbers), std::unique(std::begin(Numbers), std::end(Numbers))) << "\n";
      return 0;
    }
    


  • @Quiche-Lorraine Sehr schön. So sieht eine gute moderne Lösung aus! Hoffentlich sieht sich @Data2006 die an und lernt sie zu verstehen. Je nach verwendetem Standard könnte man std::ranges::sort und std::ranges::unique nehmen



  • Jupp. Und wenns wichtig ist, kann man anfangen zu benchmarken. Ich vermute, dass sort+unique schneller ist als der Umweg über ein set (oder ein unordered_set). Aber vielleicht hängt es auch vom Datentyp ab.

    Jedenfalls ist das schöne an der Set-Variante, dass sie kurz und einfach ist sowie das Original-Array unangetastet lässt (deswegen habe ich auch 2 Zeilen und nicht eine). Nachteil ist natürlich die Kopie. Die Variante mit sort ändert dagegen das Ursprungsarray. Wenn das ok ist, dann ists natürlich auch super. Generell bevorzuge ich immer Varianten, die die Ursprungsdaten unangetastet lassen.



  • @Schlangenmensch sagte in C++ Verständnis eines Programms:

    @Quiche-Lorraine Sehr schön. So sieht eine gute moderne Lösung aus! Hoffentlich sieht sich @Data2006 die an und lernt sie zu verstehen. Je nach verwendetem Standard könnte man std::ranges::sort und std::ranges::unique nehmen

    Ich finde es allerdingfs auf den ersten Blick nicht so leicht zu erkennen was passiert wie bei wobs Variante.



  • Meine Anforderungen an den Code sind etwas niedriger gesteckt. Ich möchte dem TE einfach zeigen, was in der STL steckt.

    Von daher finde ich die letzten Beiträge alle schön. Wenn der TE sich dies zu Herzen nimmt, wird er einiges in Sachen C++ lernen.



  • @Quiche-Lorraine

    Löbliches Vorhaben, aber der Ansatz des TE (oder des C++ Autors) ist schon Käse, da sollte man dann auch nicht mehr weitermachen. Für kleine Mengen mag das ja alles noch funktionieren, aber bei großen Datenmengen macht sich O(n²) schon bemerkbar, dann sollte man Algorithmen/Datenstrukturen, die das in O(n log n) erledigen benutzen.

    Edit: Das bezieht sich auf deinen ersten Beitrag

    @TE
    Das geht jetzt vermutlich über deinen Kenntnisstand hinaus, aber dein Codeschnispel soll die Anzahl der eindeutigen Zahlen in einer Menge von Zahlen bestimmen und hat mehrere Probleme:

    1. unpassende Datenstrukturen. Statt int array[] benutzt man besser std::array<int,7>, da kann man auch direkt die Anzahl der Elemente abfragen, statt die Speichergröße des Arrays durch die Größe des Datentyps zu teilen. Das hat man früher so gemacht.
    2. eine verschachtelte for-Schleife. Die äußere Schleife führt eine innere Schleife aus, und beide laufen im schlimmsten Fall über alle Elemente, d.h. die innere Operation wird n*n oft (=> O(n²)) aufgerufen. Für 7 Elemente ist das egal, aber mach das mal für 10.000 Elemente mit einer komplexen Operation, dann wird's träge. Hier gibt's eine Übersicht des Laufzeitverhaltens für verschiedene Komplexitätsklassen.
    3. explizite Schleifen statt Funktionen aus der STL. Bevor man etwas auf Containern selber programmiert sollte man mal schauen, ob es in der STL nicht schon Funktionen gibt, die das (oder was Ähnliches) machen, wie man selbst machen möchte. Vllt muss man seine Daten etwas umorganisieren, damit eine STL-Funktion so damit arbeiten kann, wie man möchte, aber da ist die STL schon unheimlich mächtig und flexibel.

    Wenn das alles nur zur Übung ist kannst du Punkt 3) ignorieren, solltest dich aber mal mit Punkt 2) befassen. Und Punkt 1) im Allgemeinen auch, nämlich möglichst Containerklassen aus der STL zu benutzen. Das führt zwangsläufig zu Iteratoren und Funktionen, die mit Iteratoren arbeiten, und wenn man das ein Mal verstanden hat ist man C++-technisch schon ein gutes Stück vorangekommen.



  • Die gezeigten Herangehensweisen haben schlimmstenfalls O(n²) und bestenfalls O(n) (linear). Dann sind die O(n)-Varianten natürlich besser.

    Mikrooptimierungstechnisch ist nur noch zu untersuchen, wie hoch der konstante Faktor bzw. die tatsächlichen Kosten sind, bzw. ab welcher Listengröße sich die O(n)-Variante lohnt bzw. amortisiert hat.

    Hö, was meint er jetzt damit?

    Na ja, seien die tatsächlichen Kosten einmal 2 mal n² und einmal 50 mal n. Dann lohnt sich zweitere Variante erst ab 25 Listenelementen: https://www.wolframalpha.com/input?i=2n^2%3D50n

    Das war jetzt eine rechnerische Überschlagung. Die genauen Kosten sind natürlich zu ermitteln.

    ... Und in der Folge muss eine Funktion/Methode dann natürlich anhand der Listengröße eine Fallunterscheidung vornehmen.



  • Ich hab mir mal das Video angesehen, und habe den Eindruck, dass es um eine Lösung in C geht, und nicht in C++.

    Von daher - abgesehen von anderen Schwächen Eurer Vorschläge (zB. Rückgabe im ursprünglichen Array, Veränderung der Reihenfolge) - scheint mir der ursprüngliche Lösungsansatz gar nicht so schlecht zu sein.



  • @Belli

     std::cout << "Anzahl der verschiedenen Zahlen: " << zahlVerschiedene << std::endl;
    

    Taucht das im Video auch auf?



  • @Data2006 sagte in C++ Verständnis eines Programms:

    #include <iostream>

    Das ist doch kein reines C.



  • Das stimmt wohl, ich schätze, das kommt vom TE? Das, iV mit cout ist aber auch das einzige, was nicht C ist ... schau Dir ruhig mal das Video an ...



  • @DocShoe sagte in C++ Verständnis eines Programms:

    @Belli

     std::cout << "Anzahl der verschiedenen Zahlen: " << zahlVerschiedene << std::endl;
    

    Taucht das im Video auch auf?

    Da wird nur die Funktion entwickelt, die hat keine Ausgabe .... das Einzige C++ - stylige in dem Video, das ich finde, ist die Variablendeklaration dort, wo man sie braucht, und nicht am Funktionsbeginn, aber das geht doch seit einiger Zeit auch in C, oder?



  • Ja, das ist C und kommt aus dem Wintersemester 2014/2015 an der FH Bielefeld, hier die komplette Playlist zur Vorlesung.



  • @Belli sagte in C++ Verständnis eines Programms:

    @DocShoe sagte in C++ Verständnis eines Programms:

    @Belli

     std::cout << "Anzahl der verschiedenen Zahlen: " << zahlVerschiedene << std::endl;
    

    Taucht das im Video auch auf?

    Da wird nur die Funktion entwickelt, die hat keine Ausgabe .... das Einzige C++ - stylige in dem Video, das ich finde, ist die Variablendeklaration dort, wo man sie braucht, und nicht am Funktionsbeginn, aber das geht doch seit einiger Zeit auch in C, oder?

    Ja, das geht auch in C, ist aber nicht Kernighan Ritchie ...

    Und ich schaue mir meist keine Videos an...



  • @DocShoe sagte in C++ Verständnis eines Programms:

    Ja, das ist C und kommt aus dem Wintersemester 2014/2015 an der FH Bielefeld, hier die komplette Playlist zur Vorlesung.

    Ergänzung: Das ist eine Vorlesung für Bauingenieure gewesen, wenn ich das richtig sehe.

    Ergänzung 2: Jörn Loviscach ist ein deutscher Mathematiker. Er ist Professor für Ingenieurmathematik und technische Informatik an der Fachhochschule Bielefeld sowie ehemaliger stellvertretender Chefredakteur der Computer-Zeitschrift c’t. https://de.wikipedia.org/wiki/Jörn_Loviscach

    Ergänzung 3: Ich studiere zwar auch in der Nähe, bin dem Professor aber noch nicht übern Weg gelaufen. Ich kenne die Bau-Ings nicht ... Mensch, Zufälle gibts.



  • @Fragender sagte in C++ Verständnis eines Programms:

    @Belli sagte in C++ Verständnis eines Programms:

    @DocShoe sagte in C++ Verständnis eines Programms:

    @Belli

     std::cout << "Anzahl der verschiedenen Zahlen: " << zahlVerschiedene << std::endl;
    

    Taucht das im Video auch auf?

    Da wird nur die Funktion entwickelt, die hat keine Ausgabe .... das Einzige C++ - stylige in dem Video, das ich finde, ist die Variablendeklaration dort, wo man sie braucht, und nicht am Funktionsbeginn, aber das geht doch seit einiger Zeit auch in C, oder?

    Ja, das geht auch in C, ist aber nicht Kernighan Ritchie ...

    Und ich schaue mir meist keine Videos an...

    Kein Problem, guck Du Dir die Videos von S. Wagenknecht an, ich gucke mir die C - Videos an ... dann tauschen wir uns aus.



  • Jetzt geht das wieder los. 🙄 Das hat doch nix mit dem Thema zu tun.



  • Liebe/r @Belli ,
    ich verfolge auch verschiedene Threads. Aber man sollte diese nicht mischen. Professionell ist man, wenn man Probleme von einander trennen kann.


Anmelden zum Antworten