STL-Container - Vector
-
314159265358979 schrieb:
Der vector vergrößert sich nur, wenn du explizit durch ein push_back etwas anhängst.
Genau gesagt erzeugt dein Code undefiniertes Verhalten. Der Feldoperator liest/schreibt ohne eine Bereichsprüfung. Nutze
vector::resizeodervector::push_backum ihn zu vergrössern.
-
Wie soll man das dann machen? Muss ich dann quasi die zehn Iterationen der do-while-Schleife abzählen und dann das push_back ausführen?
-
vip@r schrieb:
Wie soll man das dann machen? Muss ich dann quasi die zehn Iterationen der do-while-Schleife abzählen und dann das push_back ausführen?
Warum fängst du denn überhaupt mit 10 Elementen an?
-
vip@r schrieb:
Wie soll man das dann machen?
Statt
cin >> wert[i];schreibst du einfach:int Temp; cin >> Temp; wert.push_back(Temp);
-
vector<double> werte; ... do ... int einzelwert; cin >> einzelwert; werte.push_back( einzelwert ); ...
-
Nein, du liest den Wert innerhalb der Schleife in eine Variable ein und wirfst diese dann per push_back() in den vector<>
double wert; cin>>wert; werte.push_back(wert);
-
Hm, soweit funktioniert das jetzt. Nun möchte ich noch eine Funktion schreiben, die mir den Mittelwert berechnet. Wie übergebe ich nun am besten den Vector an die Funktion?
-
Am besten als const-Ref.
Aber wieso selber schreiben - die einfachste Lösung wäre std::accumulate()
-
In meinem C++-Buch finde ich leider keine Informationen zu accumulate()...
Kannst du mir noch ein bisschen draufhelfen?
-
-
google und die referenzen sind dein Freund:
-
Den Vector mit Zeigern oder mit einer der Standardmethoden an dei Funktion übergeben ist wohl nicht möglich?
-
vector::begin() und vector::end()

-
vip@r schrieb:
Den Vector mit Zeigern oder mit einer der Standardmethoden an dei Funktion übergeben ist wohl nicht möglich?
Klar ist es möglich, aber ist nicht sinnvoll (Übergabe als Kopie wird recht aufwendig wenn der vector<> größer wird, Übergabe als Pointer ist ein Relikt aus C-Zeiten).
-
Hm, gut. Dann ist hier wohl das an eine Funktion übergeben wohl wirklich nicht so der bringer.
Aber: Ich verstehe irgendwie nicht, dass C++ hier quasi "verweigert", bzw. es anscheinend sehr schwer macht den Vector an eine Funktion zu übergeben und in der dann den Vector mit einer for-Schleife auslesen und dann eben die Werte aufaddieren und durch 2 zu teilen.
So, wie ich das verstanden habe, benötige ich ja für accumulate() auch noch Iteratore von denen ich widerum (noch) nicht weiß wie das gehen soll...
-
vip@r schrieb:
Hm, gut. Dann ist hier wohl das an eine Funktion übergeben wohl wirklich nicht so der bringer.
Aber: Ich verstehe irgendwie nicht, dass C++ hier quasi "verweigert", bzw. es anscheinend sehr schwer macht den Vector an eine Funktion zu übergeben und in der dann den Vector mit einer for-Schleife auslesen und dann eben die Werte aufaddieren und durch 2 zu teilen.
Was heißt hier "verweigert"? Es ist möglich, vector<>en zu kopieren, du mußt nur damit rechnen, daß dort eine ganze Menge Daten zusammenkommt. Deshalb verwendet man da lieber eine (const) Referenz.
So, wie ich das verstanden habe, benötige ich ja für accumulate() auch noch Iteratore von denen ich widerum (noch) nicht weiß wie das gehen soll...
Iteratoren sind eine Abstraktion, damit die Algorithmen nicht für jeden Container neu angepasst werden müssen (außerdem kannst du mit ihnen auch blanke Arrays oder Teilbereiche deines Containers beschreiben). Und die STL-Containerklassen bieten die Methoden begin() und end(), um Iteratoren für alle Elemente zu ermitteln:
double mv = accumulate(werte.begin(),werte.end(),0.0) / werte.size();
-
Ich hab jetzt mal versucht die Mittelwertberechnung ohne Funktion zu realisieren. Dabei ist mir nun folgendes aufgefallen. Wenn der Zähler der for-Schleife auf 0 steht, dann adressiert er mir ja das Element 0 im Vector. Nur steht da eine 0 obwohl ich für das 0-te-Element eine andere Zahl als 0 eingegeben habe...
Hier der Code:
#include<iostream> #include<vector> #include<numeric> using namespace std; //void mittelwert(vector<double>* werte) //{ // int i, anzahl; // // anzahl = werte[i]; // //} int main() { int anzahl = 0, c = 0; int wert = 0, summe = 0, ergebnis = 0; vector<double> werte(1); cout << "Mittelwert-Berechnung" << endl << endl; do { cout << anzahl+1 << ". Wert angeben: "; c = cin.peek(); if(c != 'e') { cin >> wert; werte.push_back(wert); char cend = cin.get(); anzahl++; } } while(c != 'e'); cout << werte[3]; for(int i=0; i<anzahl; i=i+1) { summe = summe + werte[i]; } ergebnis = summe / anzahl; return 0; }
-
Du hast den vector<> mit einem Element angelegt, das mit 0 vorbelegt ist - die von dir eingelesenen Elemente beginnen ab Index 1.
-
Hm. Da wär ich jetzt nie drauf gekommen. Man kann anscheinend vectoren auch mit 0 vorbelegen.
So, jetzt vielleicht nochmal zum Thema vectoren an Funktionen übergeben. Wie mach ich das jetzt am Besten, bzw. ich hab dazu noch einige Frage:
double mv = accumulate(werte.begin(),werte.end(),0.0) / werte.size();Wenn ich jetzt den Code von dir anschau ist mir da jetzt einiges nicht klar. Dass die Methode size() die Anzahl der im vector<> enthaltenen Element zurückgibt hab ich erlesenen können; somit ist das klar.
Returns the result of accumulating all the values in the range [first,last) to init.
accumulate ( InputIterator first, InputIterator last, T init );
Was aber nun accumulate() genau macht ist mir noch nicht ganz klar. Laut cplusplus ist die Standardoperation das Aufsummieren aller Elemente in einem Bereich und zurückgeben des berechneten Wertes. Was mir aber nicht klar ist, ist was mit dem "init" in obigem Zitat gemeint ist. Ich kann mir zwar denken, dass die Methode .begin quasi den Wert liefert der von obiger Definition durch first gefordert ist und die Methode .end den Wert liefert der von obiger Definition durch last gefordert ist. Was aber mach nunt begin und end wirklich?
Gibts eigentlich noch eine andere Seite als cplusplus bei der man evtl. einfach er auf die Methoden-Erklärung der STL kommt?
-
vip@r schrieb:
Wenn ich jetzt den Code von dir anschau ist mir da jetzt einiges nicht klar. Dass die Methode size() die Anzahl der im vector<> enthaltenen Element zurückgibt hab ich erlesenen können; somit ist das klar.
Returns the result of accumulating all the values in the range [first,last) to init.
accumulate ( InputIterator first, InputIterator last, T init );
Was aber nun accumulate() genau macht ist mir noch nicht ganz klar. Laut cplusplus ist die Standardoperation das Aufsummieren aller Elemente in einem Bereich und zurückgeben des berechneten Wertes. Was mir aber nicht klar ist, ist was mit dem "init" in obigem Zitat gemeint ist. Ich kann mir zwar denken, dass die Methode .begin quasi den Wert liefert der von obiger Definition durch first gefordert ist und die Methode .end den Wert liefert der von obiger Definition durch last gefordert ist. Was aber mach nunt begin und end wirklich?
Du kannst dir die Iteratoren als eine Weiterentwicklung von Zeigern vorstellen - du kannst sie dereferenzieren, weiterschieben und vergleichen. begin() liefert einen Iterator auf den Anfang des Containers, end() einen auf das Ende (genauer: hinter das letzte Element), damit hast du einen Bereich, den du als first/last an den Algorithmus übergeben kannst.
Der Wertinitist der Startwert für die Summierung (und entspricht demsumme = 0bei deiner manuellen Schleife. Der ist nötig, weil dort je nach Anwendung andere Ausgangswerte notwendig werden könnten, z.B.://geometrisches Mittel: double geo = pow( accumulate(werte.begin(),werte.end(),1.0,multiplies<double>), 1/werte.size() ); //String-Verkettung: vector<string> zeilen; ... string datei = accumulate(zeilen.begin(),zeilen.end(),string());