Modalwert aus Vector finden (Stroustrup)
-
enf elem schrieb:
Sortieren ist langsam. Den Median erhält man mit
std::nth_element
.Vom Median ist ja auch nicht die Rede.
-
Ich hab jetzt noch was mit sortieren zu bieten:
int main() { vector<int> val {4,0,4,2,2,4,5,33}; sort(val.begin(),val.end()); int m=0; for (int i=0; i<val.size(); ++i) { if (val[i]==val[i+1]) m=val[i]; } cout<<"Modalwert="<<m; }
Ist das Ok soweit?
-
Du brauchst die
#includes
und dasusing namespace std;
nicht abzuschneiden. Das macht copy und paste nur umständlicher für alle, die Deinen Code kompiliern möchten.Es gibt neben
operator[]()
noch den Zugriff auf Vektorelemente mitat()
.at()
kontrolliert ob der Index auf den zugegriffen wird gültig ist.
Da gibt es dann eine Überraschung, wenn Du Z. 8 und 9 ersetzt:if (val.at(i)==val.at(i+1)) m=val.at(i);
-
Ist das Ok soweit?
Nein, du liest jenseits der Vectorgrenzen:
for (int i=0; i<val.size(); ++i) { if(val[i]==val[i+1]) // ^^^^^ da m=val[i]; }
Davon abgesehen ist deine Implementierung auch falsch. Versuch mal diesen vector:
{0, 2, 4, 0, 0, 0, 0, 0, 2, 4}
Dein Algorithmus sucht die letzte Zahl, die mindestens zweimal vorkommt.
Vorgehensweise: Sortieren, zählen bis eine neue Zahl kommt. Dann neu zählen. Wenn die neue Zahl öfter vorkommt, als die alte: neue Zahl merken, neue Anzahl merken, weitermachen.
-
nächster Versuch:
// Modalwert aus Reihe ganzer positiver Zahlen #include<iostream> #include<string> #include<vector> #include<algorithm> #include<cmath> using namespace std; int main() { vector<int> val {0, 2, 4, 0, 0, 0, 0, 0, 2, 4}; sort(val.begin(),val.end()); int counter_old=0; int counter_new=0; int cur_max=0; for (int i=0; i<val.size(); ++i) { if (i>0 && val[i]==val[i-1]) // Wenn 2. Wert im Vektor gleich dem 1. { counter_old=++counter_old; // alten Zähler erhöhen if (counter_old>counter_new) // wenn alter Zähler größer Vektorwert in cur_max speichern { cur_max=val[i]; counter_new=counter_old; } } else counter_old=0; // Wenn Vektor Paar ungleich alten Zähler zurücksetzen } cout<<"M="<<cur_max<<endl; }
-
pauledd schrieb:
nächster Versuch:
if (i>0 && val[i]==val[i-1]) // Wenn 2. Wert im Vektor gleich dem
Selbst, wenn du es hier mit i>0 abfängst es ist immer eine schlechte Idee im Vector vor oder zurückzugucken.
Guck Dir mal die Lösung an die ich geschrieben habe und tausch die iteratoren einfach mit richtigen ints aus oder merk dir die last_number einfach.
Du kannst es natürlich auch mit einem bool lösen aber +1 , -1 im Vector ist selbst mit abfangen eine schlechte Lösung. (Nach meiner Meinung)Wenn du es mit iteratoren machst musst du nicht kopieren ansonsten kopier, das int einfach das kostet nichts.
-
Ok ich schau mir nochmal dein Code an. Aber ich denke ich habe die Aufgabe im Rahmen der bisher behandelten Mittel des Buches gelöst da ich den Begriff "Iterator" bzw. "const_iterator" noch nicht gelesen habe (kommt irgendwo ab Seite 700 :D, bin auf Seite 155).
Ein paar Fragen zu deinem Code:
warum schreibst du eigentlich immer das
std::
davor?
was macht das auto in ?
for (auto cit...
was macht das * hier?
if (*cit == *last_number)
-
pauledd schrieb:
std::
davor?
Das ist einfach Gewohnheit, da ich schon oben using namespace std; geschrieben habe ist es eigentlich nicht nötig.
Wenn du deinen Source -Code in Header(hpp) und CPP files trennst, wirst du die using deklarationen, wenn überhaupt nur im cpp File haben.pauledd schrieb:
was macht das auto in ?
C++:for (auto cit...
auto ist einfach etwas für Schreibfaule, gerade bei iteratoren ist es manchmal ziemlich anstrengend den Typ genau aufzuschreiben.
std::cbegin(val); // returned einen vector<int>::const_iterator // das auto macht es überflüssig es explizit hinzuschreiben for (auto cit = std::cbegin(val); // und for (std::vector<int>::const_iterator cit; // sind das gleiche, das andere ist aber kürzer
pauledd schrieb:
was macht das * hier?
if (*cit == *last_number)
Wahrscheinlich bist du in deinem Buch noch nicht zu Pointern gekommen.
Ein iterator ist ein Objekt der in einem Container auf ein gewisses Objekt zeigt.
Wenn ich einfach "==" ohne "" verwenden würde, würde ich den Computer fragen sind die Iteratoren cit und last_number gleich.
Mit anderen Worten zeigen die beiden Iteratoren auf das gleiche Element im Container.
Ich möchte aber wissen ob das Value auf, dass sie zeigen gleich ist und dafür muss ich den Iterator mit "" dereferenzieren.Ich hoffe, dass war halbwegs verständlich.
-
Das mit den Iteratoren kannste dir so vorstellen:
int begin = 0u; // Iterator auf Anfang: vector<int>::iterator begin = vec.begin(); int end = vec.size(); // Iterator auf Ende: vector<int>::iterator end = vec.end() ++begin; // gehe zum nächsten Element: ++begin vec[begin]; // lese Wert an Stelle begin: *begin begin == end; // vergleiche die Position von begin mit end: begin == end
-
Ruvi schrieb:
Wahrscheinlich bist du in deinem Buch noch nicht zu Pointern gekommen.
So ist es.
So ganz erschließt sich mir das noch nicht aber vielen Dank für eure
Erläuterungen. Ich werde diesen Thread sicher nocheinmal aufsuchen
und dann mit fortgeschrittenem Wissen herangehen.