zweidimensionalen Vektor ausgeben



  • Guten Tag zusammen,

    ich habe ein Problem bei der Ausgabe eines zweidimensionalen Vektors.

    Ich habe einen Vektor "rohdaten" mit Nullen und verschieden langen Zahlenpaketen gefüllt (Bsp: 0,0,0,14,15,16,0,0,0,0,0,14,15,16,17,18,0,0,0,0).
    Nun möchte ich jedes zusammenhängende Zahlenpaket in einem neuen Vektor speichern.
    Mein Programm ließ sich bis zum folgenden Punkt problemlos kompilieren:

    vector<vector<int> > hindernisse;
    vector<int> hindernis;
    int zaehler = 0;
    fuelle_rohdaten();
    
    for(unsigned i = 0; i < rohdaten.size(); i++){
      if(rohdaten[i] != 0 && rohdaten[i+1] != 0){
         hindernis.push_back(rohdaten[i]);
      }
      if(rohdaten[i] != 0 && rohdaten[i+1] == 0){
        hindernis.push_back(rohdaten[i]);
        hindernisse.push_back(hindernis);
        hindernis.resize(0);
        ++zaehler;
      }
    }
    

    Soweit ich bis hierhin keinen Mist programmiert habe, gehe ich meinen Vektor "rohdaten durch und pushe jede Zahl ungleich Null in den Vektor "hindernis". Sobald ich an der letzten Zahl eines Pakets angekommen bin, pushe ich den Vektor "hindernis" in den 2d-Vektor "hindernisse". Anschließend "leere" ich den Vekor "hindernis" durch hindernis.resize(0).

    Jetzt möchte ich die Zahlenpakete ausgeben. Dazu habe ich folgende Schleife benutzt:

    for(int i = 0; i < zaehler; i++){
        cout << "Hindernis " << zaehler << ":" << hindernisse[i] << endl;
    }
    

    Leider funktioniert das nicht und ich bekomme einen Fehler.
    Fehler: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
    cout << "Hindernis " << zaehler << ":" << hindernisse[i] << endl;

    Mir fällt sonst keine andere Möglichkeit ein, wie ich jedes Zahlenpaket mit unterschiedlich vielen Einträgen ausgeben lassen kann.

    Ich hoffe ihr könnt mir helfen und einen Tipp geben, wie ich mein Ziel erreichen kann.

    Liebe Grüße
    ^





  • Du pushst deine Zahl nur in einen Vektor wenn auch die nächste Zahl ungleich Null ist. Ich denke nicht, dass das geplant ist.
    ////EDIT: Sry, hab mich auf die Schnelle in deinen If Verzweigungen verlesen, scheint doch zu passen.////

    Zu deiner Ausgabe, wenn du c++11 Feature nutzen kannst/darfst:

    for(auto h:hindernisse){
       for(auto i:h){
          std::cout << i << " ";
          }
       std::cout << std::endl;
       }
    


  • Du zählst den Index i um 1 zu hoch:

    for(unsigned i = 0; i < rohdaten.size(); i++)
    {
      if(rohdaten[i] != 0 && 
         rohdaten[i+1] != 0) // greift evtl. auf ungültiges Element zu
    


  • Danke Schlangenmensch!! Deine Lösung funktioniert genau so, wie ich es haben möchte 🙂

    Über das Thema Operatoren überladen bin ich schon öfter gestolpert, aber das hab ich nicht wirklich verstanden.

    Da gesagt wurde, dass ich mein "i" ggf. zu hoch zähle: Wird in der if-Schleife nicht die Bedingungen nacheinander geprüft? Dies würde bedeuten, dass die Bedingung rohdaten[i+1] doch eh nicht geprüft werden würde, wenn rohdaten[i] = 0 ist oder?

    Insgesamt möchte ich mich aber bei allen für die Hilfe und die Tipps bedanken! 🙂



  • käsebrot95 schrieb:

    Da gesagt wurde, dass ich mein "i" ggf. zu hoch zähle: Wird in der if-Schleife nicht die Bedingungen nacheinander geprüft?

    if-Schleifen prüfen eigentlich keine Bedingungen. "Bedingungen" sind einfach Ausdrücke, die Ausgewertet werden. Aber das "tut" nicht irgendwie die if-Schleife, sondern der Prozessor. Danach wird abhängig von dem Ergebnis dieser Auswertung in den Schleifenkörper der if-Schleife gesprungen (bzw. anders rum: bei unwahrem if-Schleifenargument über den if-Schleifenkörper hinweg).

    käsebrot95 schrieb:

    Dies würde bedeuten, dass die Bedingung rohdaten[i+1] doch eh nicht geprüft werden würde, wenn rohdaten[i] = 0 ist oder?

    Das stimmt im Falle von rohdaten[i] != 0 && rohdaten[i+1] != 0 . Ergibt sich jedoch nicht daraus, daß eine if-Schleife irgendwas der Reihe nach tun würde, sondern aufgrund der in C und C++ vereinbarten Short-circuit evaluation.

    Ich fürchte aber, Du hast das Problem mit Deinem Code nicht wirklich verstanden:

    for( unsigned i = 0; i < rohdaten.size(); i++ ) {
        if( rohdaten[ i     ] != 0 &&
            rohdaten[ i + 1 ] != 0 ) {
            // ...
        }
    
        if( rohdaten[ i     ] != 0 &&
            rohdaten[ i + 1 ] == 0 ) {
            // ...
        }
    }
    

    mit

    rohdaten = { 1, 2, 3, 4, 5 };
    rohdaten.size() sei damit 5

    { // i = 0;
        if( rohdaten[ 0 ] != 0 &&
            rohdaten[ 1 ] != 0 ) {
            // ...
        }
    
        if( rohdaten[ 0 ] != 0 &&
            rohdaten[ 1 ] == 0 ) {
            // ...
        }
    }
    { // i = 1;
        if( rohdaten[ 1 ] != 0 &&
            rohdaten[ 2 ] != 0 ) {
            // ...
        }
    
        if( rohdaten[ 1 ] != 0 &&
            rohdaten[ 2 ] == 0 ) {
            // ...
        }
    }
    { // i = 2;
        if( rohdaten[ 2 ] != 0 &&
            rohdaten[ 3 ] != 0 ) {
            // ...
        }
    
        if( rohdaten[ 2 ] != 0 &&
            rohdaten[ 3 ] == 0 ) {
            // ...
        }
    }
    { // i = 3;
        if( rohdaten[ 3 ] != 0 &&
            rohdaten[ 4 ] != 0 ) {
            // ...
        }
    
        if( rohdaten[ 3 ] != 0 &&
            rohdaten[ 4 ] == 0 ) {
            // ...
        }
    }
    { // i = 4;
        if( rohdaten[ 4 ] != 0 &&               // 5 != 0 --> true --> weiter Auswerten
            rohdaten[ 5 ] != 0 ) {              // zugriff auf rohdaten[5] --> booom!
            // ...
        }
    
        if( rohdaten[ 4 ] != 0 &&
            rohdaten[ 5 ] == 0 ) {
            // ...
        }
    }
    


  • @Swordfish: Du bist doch schon lange dabei. Erzähle nichts von if-Schleifen, auch wenn käsebrot95 selbst als Anfänger diesen Begriff verwendet. if-Schleifen gibt es nicht.



  • Was ist ein Name? Was uns Rose heißt, wie es auch hieße, würde lieblich duften.


  • Mod

    Swordfish schrieb:

    Was ist ein Name? Was uns Rose heißt, wie es auch hieße, würde lieblich duften.

    Dein ontologisches Poem ist keine Rechtfertigung dafuer, einen laecherlichen Misnomer zu benutzen. Wenn du von einer if-Schleife sprichst, habe bspw. ich per se keine Ahnung, was das sein soll, und das ist schlicht und ergreifend ein Kommunikationshindernis.



  • Petzi, wennst spaßbefreit bist, dann editierst einfach den Beitrag und löschst das drauffolgende ...

    // falls nicht: http://if-schleife.de/ ... allerdings find ich "if-Abfrage" fast noch hässlicher als "if-Schleife" 😉



  • Danke swordfish, jetzt verstehe ich, was dem zu hoch zählen gemeint war! Dann werde ich mir noch etwas überlegen, um das zugreifen auf ein ungültiges Element auszulassen.

    Wie bereits erkannt bin ich Anfänger und mit dem Begriff "if-Schleife" zufrieden, auch wenn das nicht ganz korrekt sein mag 😉 ich nehme diesen Punkt mit und werde demnächst mein Vokabular diesbezüglich verbessern 🙂

    Danke für die Hilfe und die ausführliche Erklärung!!



  • käsebrot95 schrieb:

    Dann werde ich mir noch etwas überlegen, um das zugreifen auf ein ungültiges Element auszulassen.

    Würd ich an Deiner Stelle dann nochmal hier checken lassen. Es besteht die Gefahr, daß Du zu umwegig denkst.



  • also ich hab jetzt folgende Lösung erarbeitet, es scheint auch zu funktionieren:

    ich erzeuge den Vektor rohdaten immer so, dass der letzte Eintrag eine NULL ist. So müsste ja zumindest die Bedingung

    rohdaten[i] !=0
    

    am letzten Eintrag von "rohdaten" nie erfüllt sein, sodass die if-Anweisung übersprungen werden kann und gar nicht erst auf

    rohdaten[i+1]
    

    an letzter Stelle zugegriffen werden muss.

    Passt das so oder ist da wieder ein Denkfehler drin?



  • Das ist sehr unschön. NULL ist ursprünglich nur ein Ausdruck für 0. Und es funktioniert auch nur deswegen. In modernem c++ sollte man dass Schlüsselwort nullptr benutzten. Dein ursprünglicher
    Ansatz hat funktioniert weil eine “0“ am Ende des Vektors stand, so wie jetzt NULL.

    Du solltest in einer Schleife, die über die Anzahl der Elemente in einem Vektor iteriert, nicht auf i+1 zugreifen.



  • oh verdammt, ich hab mich falsch ausgedrückt: bei mir steht am ende eine "0" und nicht "NULL"....



  • Dann musst du IMMER daran denken, dass dein Vektor mit einer 0 abgeschlossen wird.
    Du solltest dir angewöhnen dein Programmcode so zu schreiben, dass er alle Eventualitäten abdeckt.

    Versuch doch dein Code so umzuschreiben, dass du nicht mehr auf [i+1] zugreifen musst.



  • Meine Aufgabe ist/war es, zusammenhängende Zahlenpakete zu finden und getrennt voneinander zu speichern.

    Ich habe mir zunächst überlegt, wie man solch ein Zahlenpaket überhaupt erkennen kann. Das wesentliche Kriterium ist in meinem Fall doch, dass vor und nach einem Zahlenpaket "0" stehen. Um dies zu prüfen ist ein Vergleich mit dem folgenden Element notwendig.

    Daher fällt mir nichts ein, wie ich nicht auf das Element [i+1] zugreifen muss. Oder gibt es bei C++ eine Möglichkeit, dass das letzte Element eines Vektors erkannt wird? Dann könnte man doch eine Ausnahme für das letzte Element schreiben, sodass nicht auf ein ungültiges Element evtl zugegriffen wird.

    Dann Vergleich zweier, aufeinander folgender Elemente mit [i+1] kann ich aber doch nicht komplett weglassen oder?

    Wie gesagt, ich bin noch nicht wirklich vertraut mit C++, in den Einführungswerken zu C++ habe ich bisher keine anderen Vergleichsmöglichkeiten gefunden.



  • Das Problem hat mit C++ nichts zu tun, es ist ein Logikproblem. Wenn du Zahlenpaare finden sollst, wieviele Zahlen brauchst dann für ein Paar? 😃
    Wenn du nur ein Element hast, wieviele Paare kannst du daraus bilden?
    Und wenn du 3 Elemente hast, wieviele Paare kannst du daraus bilden?
    Grob: Wenn du N Elemente hast, wieviel Paare kannst du daraus bilden?
    Ein Paar ist zwei aufeinander folgende Zahlen.



  • Du hast eine Liste von Zahlen die du auf Pakete aufteilen sollst.

    z.B. {1,1,0,2,2,2,2,0,0,0,3,3} -> 3 Pakete

    Was hat jetzt die folgende Zahl damit zu tun, ob die Zahl die du dir anschaust zu dem Paket gehört?

    Also, nehm die erste Zahl "1". Was hat die zweite "1" damit zu tun ob die erste eins zu einem Zahlenpaket gehört?



  • ich glaube es dämmert bei mir... aber nur ganz langsam 😉

    nach dem beispiel von schlangenmensch würde ich sagen, dass die zweite "1" zum Zahlenpaket gehört, weil dazwischen keine "0" aufgetaucht ist. Sie hat aber nichts direkt mit der ersten "1" zu tun...


Log in to reply