C++ Verständnis eines Programms



  • Moin zusammen,

    über youTube habe ich dieses Video gefunden:
    https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DHWIsmov0CVI%26t%3D63s%26fbclid%3DIwAR0DSzT250qXbvghKUyKcy4qSmeGGeYttfZc0U3nJnpVssEVvzoB8-Yimws&h=AT2Tw-LmVSqUo1O7Omd4j8Fjd7s_AZ8mPo0RoCoPZejMipgCfikIkBArfGP_yGK_O_efkSVZRRy5mj5qVdO_mRoenLEDRcUYqZqr7FG5rqa0-RdkI6n6h3ToPH5t0EKI_1Z6EdhutdIk_xq1mVCh&tn=-UK-R]-R&c[0]=AT3T-pJOvpES4MJjkXwC5rhbQfSH-udeU6Gcck9EtTMyTrOJfDCkR4YKZHh7oIP_le3GPImsjirDeLimK0MgbqOeWn1ueIQ3-StWNWXK0SvqUUhYOzX4AFGA8IUpR0ZCWaUNwFVuRRj8dDb1GIf7Pz-lK-IZSnYsMO3ii9dYw7rGGMwFRECGwFzQFx5KJN9VyRqW6LfjGvJ1NZu4XrWNN51aTDRwRPa8XpOgOObOK2ESqihY&c[1]=AT3T-pJOvpES4MJjkXwC5rhbQfSH-udeU6Gcck9EtTMyTrOJfDCkR4YKZHh7oIP_le3GPImsjirDeLimK0MgbqOeWn1ueIQ3-StWNWXK0SvqUUhYOzX4AFGA8IUpR0ZCWaUNwFVuRRj8dDb1GIf7Pz-lK-IZSnYsMO3ii9dYw7rGGMwFRECGwFzQFx5KJN9VyRqW6LfjGvJ1NZu4XrWNN51aTDRwRPa8XpOgOObOK2ESqihY

    Ich habe dieses Pogramm mal probiert. Allerdings nicht extra in einer eigenen Funktion, sondern unter main():

    #include <iostream>
    int main()
    {
        int array[] = { 13,42,13,23,11,5,42 };
        int zahlVerschiedene = 0;
        for (int i = 0; i < sizeof(array) / sizeof(int); i++)
        {
            bool hattenWir = false;
            for (int x = 0; x < zahlVerschiedene; x++)
            {
                if (array[i] == array[x])
                {
                    hattenWir = true;
                    break;
                }
            }
            if (!hattenWir)
            {
                array[zahlVerschiedene] = array[i];
                zahlVerschiedene++;
            }
        }
        std::cout << "Anzahl der verschiedenen Zahlen: " << zahlVerschiedene << std::endl;
    }
    

    Könnte mir jemand das Programm mal erklären? Ich gebe zu, ich habe es nicht verstanden 🙁
    Zusätzlich sollen die verschiedenen Zahlen im array aufgerückt hintereinander stehen.
    Wie bekomme ich das am besten? Vom Bauch her würde ich sagen ein 2. Ziel-Array anzulegen mit der Anzahl der verschiedenen Zahlen. Und dann ins Ziel-Array kopieren. Und diese Zahlen zurück ins Ausgangs-array kopieren.
    Lieben Dank Euch,
    Heiko

    PS: Was ein array ist weiß ich. Verstehe auch einzelne Anweisungen, nur eben nicht das Programm an sich.



  • So ein Schmarrn, vergiss das wieder.



  • Hi.

    Warum soll ich es vergessen? Das Programm vergessen oder auch die ganze Aufgabe aus dem YouTube-Video?

    LG Heiko



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

    über youTube habe ich dieses Video gefunden: https://l.facebook.com/l.php?u=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DHWIsmov0CVI%26t%3D63s%26fbclid%3DIwAR0DSzT250qXbvghKUyKcy4qSmeGGeYttfZc0U3nJnpVssEVvzoB8-Yimws&h=AT2Tw-LmVSqUo1O7Omd4j8Fjd7s_AZ8mPo0RoCoPZejMipgCfikIkBArfGP_yGK_O_efkSVZRRy5mj5qVdO_mRoenLEDRcUYqZqr7FG5rqa0-RdkI6n6h3ToPH5t0EKI_1Z6EdhutdIk_xq1mVCh&tn=-UK-R]-R&c[0]=AT3T-pJOvpES4MJjkXwC5rhbQfSH-udeU6Gcck9EtTMyTrOJfDCkR4YKZHh7oIP_le3GPImsjirDeLimK0MgbqOeWn1ueIQ3-StWNWXK0SvqUUhYOzX4AFGA8IUpR0ZCWaUNwFVuRRj8dDb1GIf7Pz-lK-IZSnYsMO3ii9dYw7rGGMwFRECGwFzQFx5KJN9VyRqW6LfjGvJ1NZu4XrWNN51aTDRwRPa8XpOgOObOK2ESqihY&c[1]=AT3T-pJOvpES4MJjkXwC5rhbQfSH-udeU6Gcck9EtTMyTrOJfDCkR4YKZHh7oIP_le3GPImsjirDeLimK0MgbqOeWn1ueIQ3-StWNWXK0SvqUUhYOzX4AFGA8IUpR0ZCWaUNwFVuRRj8dDb1GIf7Pz-lK-IZSnYsMO3ii9dYw7rGGMwFRECGwFzQFx5KJN9VyRqW6LfjGvJ1NZu4XrWNN51aTDRwRPa8XpOgOObOK2ESqihY

    Das sieht weder nach YouTube noch facebook aus...

    Beschreibe am besten in einfachen Worten, was das Programm tun soll.



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

    Zusätzlich sollen die verschiedenen Zahlen im array aufgerückt hintereinander stehen.

    Das sollten sie am Ende des Programms bereits tun, prüf das doch mal.



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

    PS: Was ein array ist weiß ich. Verstehe auch einzelne Anweisungen, nur eben nicht das Programm an sich.

    Dann geh das Programm doch Anweisung für Anweisung durch und schreib dir auf, was passiert und was an welchen Stellen in den Variablen was für Werte stehen.

    Faule Leute würden dafür einen Debugger nutzen 😉

    Ansonsten hat das wenig mit C++ zu tun, wenn du wirklich Interesse daran hast, dich mit C++ zu beschäftigen, solltest du dir vielleicht eine andere Quelle suchen.



  • @Data2006

    Ich bin mal lieb. Eine modernere Lösung sieht so aus:

    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    
    int main()
    {
      const std::vector<int> Numbers { 13, 42, 13, 23, 11, 5, 42 };  // https://en.cppreference.com/w/cpp/container
      std::vector<int> UniqueNumbers;
    
      std::for_each(std::begin(Numbers), std::end(Numbers), [&](int v) { // https://en.cppreference.com/w/cpp/language/lambda
        // Prüfe ob Wert v bereits in UniqueNumbers. Ist dies nicht der Fall, so füge v UniqueNumbers hinzu.
        if (std::find(std::begin(UniqueNumbers), std::end(UniqueNumbers), v) == std::end(UniqueNumbers))
          UniqueNumbers.push_back(v);
        }
      );
      std::cout << "Anzahl der verschiedenen Zahlen: " << UniqueNumbers.size() << "\n";
      return 0;
    }
    


  • 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 ...


Anmelden zum Antworten