[Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen


  • Mod

    @Swordfish sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    [...] In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand.

    Interpretiere ich in Bezug auf

    int i = 42;
    i = i++;
    

    so, daß zuerst i++ ausgewertet wird (i = 43) und dann zugewiesen wird.

    Das ist schon richtig. Aber value computation meint immer nur die Bestimmung des Wertes eines Ausdrucks, nicht die damit verbundenen Nebeneffekte. Wie diese mit zusammenhängen, hängt von der konkreten Ausdrucksart zusammen.

    Dein Zitat gibt die Aufeinanderfolge der Auswertung der Operanden vor, und wie sich der Nebeneffekt der Zuweisung dort einreiht.
    7.1.6.5/1 bestimmt, dass der Nebeneffekt des Inkrementierens nach der Bestimmung des Wertes dieses Ausdrucks (also der Ermittelung des alten Wertes zwecks Weiterverwendung) stattfindet. Wir wissen hier hier also nur, dass beide Nebeneffekte nach der Auswertung des Inkrementausdrucks stattfinden, und zusätzlich, dass der Nebeneffekt der Zuweisung, vor der Wertbestimmung der Zuweisung stattfindet (das macht Mehrfachzuweisung möglich). Es genügt aber nicht, um eine Reihenfolge der beiden Nebeneffkte zu etablieren.



  • @Swordfish mhh.. das ist irgendwie untergegangen.
    Weiß auch grade nicht wie ich das sinnvoll umsetzen soll, da ich ja jetzt nur noch mit der while-Schleife arbeite..
    Ich habe die Aufgabenstellung nochmal gelesen und gemerkt das ich voll am Thema vorbeigarbeitet habe..
    Sollte prüfen wie oft 3 aufeinanderfolgende Zahlen in dem Intervall liegen..
    Hab jetzt noch eine Ausgabedatei hinzugefügt, in der die Zahlen aufgelistet werden..
    Das funktioniert alles soweit.
    Wo soll ich denn dann prüfen, wann das Ende erreicht ist?

    nochmal der Code zu dieser anderen Aufgabenstellung:

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        float next;
        char komma;
        int gleich=0;
        float zahl;
        float vorgaenger=2;
        float vorvorgaenger=3; 
        float untere=0.46;
        float obere=0.54; 
        
        fstream file;
        file.open("U12KASRO.dat", ios::in);
        fstream out;
        out.open("Intervall.dat", ios::out);
        
        while (!file.eof())
        {
        	file >> next;
        	file >> komma;
        	zahl = next;
        	if(zahl >= untere && zahl <= obere && vorgaenger>=untere && vorgaenger<=obere && vorvorgaenger>=untere &&   vorvorgaenger<=obere)
    		{
    				gleich++;
    				out << vorvorgaenger << "," << vorgaenger << "," << zahl << ",";
    		}
    		vorvorgaenger=vorgaenger;
    		vorgaenger=zahl;
    	}
    	out.close();
    	file.close();
    	cout << "Die Anzahl dreier Folgeglieder im gegebenen Intervall beträgt: " << gleich;
    	return 0;
    }
    

    Viele Grüße,
    ein heute sehr verwirrter Marco



  • So liest du eine float Zahl richtig. Um das Komma-Zeichen zu verwerfen, brauchst du auch keine extra Variable. Dafür ist file.ignore() da.

    for(float zahl; file>>zahl;file.ignore())
    {
     // Deine Datenverarbeitung
    }
    


  • @out Ich würde eher file.ignore(std::numeric_limits<std::streamsize>::max(), ',') nehmen weil file.ignore() nur ein Zeichen wegwirft. Sind also zB Leerzeichen vor dem Komma failed das nächste file >> zahl daran.



  • @camper sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    Wir wissen hier hier also nur, dass beide Nebeneffekte nach der Auswertung des Inkrementausdrucks stattfinden, und zusätzlich, dass der Nebeneffekt der Zuweisung, vor der Wertbestimmung der Zuweisung stattfindet (das macht Mehrfachzuweisung möglich). Es genügt aber nicht, um eine Reihenfolge der beiden Nebeneffkte zu etablieren.

    Ok, das gibt Sinn. Danke!



  • @Swordfish Stimmt.

    Ein anderer Lösungsweg wäre:

    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <iterator>
    #include <sstream>
    using namespace std;
    // Verbessert nach Swordfish
    int main()
    {
        istringstream iss{ "1, 9, 0.47, 0.49, 0.53, 0.5, 9, 0.51, 0.52, 0.53" };
        auto count{0};
        vector<float> nums{};
        
        for( float num; iss >> num; iss.ignore(numeric_limits<streamsize>::max(),',') )
        {
            if( nums.size() < 3 )
            {
                nums.emplace_back( num );
                continue;
            }
            rotate( begin(nums), begin(nums)+1, end(nums) );
            nums[2] = num;
            
            if( all_of( begin(nums), end(nums), [](float num){return num>=0.46 && num<=0.54;} ))
                ++count;
        }
        cout << "Wie oft: " << count << endl;
    }
    
    
    

    Epsilon-Vergleich müsste noch rein, sonst fallen die Grenzen ggf. durch😁



  • @out Ich kauf' ein continue und werfe dafür ein else samt Klammern und nums.size()==3 && weg.



  • @Swordfish sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    @out Ich kauf' ein continue und werfe dafür ein else samt Klammern und nums.size()==3 && weg.

    🙃 DONE



  • @out Der Kommentar hätte aber nicht sein müssen ^^

    @Marco_der_Noob sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    Wo soll ich denn dann prüfen, wann das Ende erreicht ist?

    file >> next; muss geklappt haben, bevor du mit der Verarbeitung weitermachst.

    Eine weitere Möglichkeit zu der von @out gezeigten um bei Deiner while-Schleife zu bleiben:

    while(file >> next) {
        // have fun with next
        // ...
        // swallow ',' or '\n' or whatever
    }
    


  • Dieser Beitrag wurde gelöscht!


  • @Swordfish sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    Ich würde eher file.ignore(std::numeric_limitsstd::streamsize::max(), ',') nehmen weil file.ignore() nur ein Zeichen wegwirft.

    Davon würde ich abraten. Du bekommst dann nämlich nicht mit, wenn die Inputdatei fehlerhaft ist. Also zum Beispiel "12 x Hallo ,3" enthält. Das liest bei dir erfolgreich 12 und 3. Normalerweise ist skipws an, d.h. man kann eine Zahl oder ein Zeichen lesen und überspringt dabei automatisch whitespace. Bei Erfolg vom Einlesen der Zahl liest man noch ein char ein und vergleicht es mit ',' bzw überprüft auf eof.



  • @wob Das ist mir schon klar, daß ignore() nicht geeignet ist um ein Dateiformat zu verifizieren. War auch nicht der Anspruch.



  • Ich finde, dass gerade beim Lesen von externen Dateien unbedingt ein Check auf Gültigkeit dazugehört - immer!
    Vielleicht bin ich zu sehr durch sich ständig ändernde Formate gebrandmarkt. Egal, ob man mit einem Kunden schriftlich irgendein Format vereinbart, es kommt doch was anderes raus. Sogar wenn man eine Woche lang täglich korrekte Datenupdates erhält - plötzlich ändert sich das Format und niemand weiß, warum. Daher: FORMATE IMMER ÜBERPRÜFEN. Man sollte gar nicht erst damit anfangen, beliebig viele Zeichen bis zu einem Komma zu ignorieren, wenn man eigentlich nur Whitespace überspringen will.



  • @wob Da stimme ich Dir voll und ganz zu, nur

    @Marco_der_Noob sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    im Rahmen eines Praktikums mit dem Thema True-Random-Number-Generator habe ich eine Datei "U12KASRO.dat" mit einer Milllion Zufallszufallszahlen im Bereich zwischen 0 und 1 getrennt durch ein Komma.

    ... ich weiß nicht.



  • Danke nochmal für die zahlreichen Vorschläge und Anmerkungen.

    Die Zufallzahlen habe ich im Rahmen des Praktikums selbst erzeugt. Zum einen habe ich durch lineare Kongruenzgeneratoren (C-intern / Modulo-Funktion) Pseudozufallszahlen erzeugt und für die echten Zufallszahlen einen externen Quantis-Zufallszahlengenerator benutzt. Das Format habe ich somit selbst vorgegeben.

    Ich werde mein C++-Wissen noch etwas erweitern um euren Code auch 100% zu kapieren.

    Bis zum nächsten Problem,
    Marco



  • @Marco_der_Noob sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    Das Format habe ich somit selbst vorgegeben.

    Dann hätt' ich an Deiner Stelle die Kommas weggelassen:

    #include <vector>
    #include <fstream>
    #include <iostream>
    #include <iterator>
    
    using namespace std;
    
    int main()
    {
    	char const *filename = "test.txt";
    	std::ifstream is{ filename };
    	if (!is.is_open()) {
    		std::cerr << "Couldn't open \"" << filename << "\" for reading :(\n\n";
    		return EXIT_FAILURE;
    	}
    
    	std::vector<float> numbers{ std::istream_iterator<float>{ is },
    								std::istream_iterator<float>{} };
    
    	// und schon sind die zahlen in numbers.
    }
    

    😉



  • @Swordfish Bei den anderen Programmen habe ich die Tests gleich eingebunden.. Aber die Quantis-Daten habe ich in jugendlichen Leichtsinn mit Komma getrennt. Wollte nicht mein Excel,Mathematica,IGOR,Origin,... mit einer Milllion Zahlen quälen

    Die Kommas sind mir egal, das Ergebnis passt. So fertig nun. Hab noch genug andere Baustellen am Laufen. Physik-Studium ist kein Ponyhof.
    C++ ist in der Prioritätsliste jedenfalls gestiegen.



  • @Marco_der_Noob Die Kommas würdest Du mit einem Texteditor und Find&Replace in Null-Komma-Nix (no pun 😛 ) los.



  • @Swordfish Mit Zufallszahlen kann man noch lustige 3D-Plots usw. machen.. Jede Menge Mist um Studenten zu ärgern. Da müssen noch einige Programme an ihre Grenzen gebracht werden, bevor das Ruhe hat. Aber der C++ Teil ist jetzt notdürftig zusammengeflickt.



  • @Marco_der_Noob sagte in [Gelöst] Erfassung von drei gleichen Folgegliedern bei Zufallszahlen:

    Aber der C++ Teil ist jetzt notdürftig zusammengeflickt.

    😨 ... 😜 👍🏻


Anmelden zum Antworten