Frage

Kein Zweifel, einige von euch meinen letzten Eintrag gesehen haben, alle das gleiche Programm in Bezug auf. Ich halte Probleme mit ihm laufen. Um es zu wiederholen: noch lernen, nicht sehr weit fortgeschritten, nicht verstehen Zeiger sehr gut, nicht eine Klasse, nicht verstehen, OOP-Konzepte überhaupt, usw. Dieser Code verschmilzt nur zwei sortierte Vektoren, Farray und SFeld, in einem einzigen sortiert Vektor. Zumindest hoffe ich, dass das, was sie tut. Sagen Sie mir:

    //int num is to find the size of the original vector and
    //build up farray and sarray; not used in the merge process
    int num = original.size() 
    std::vector<int> final;

    std::vector<int>::iterator it = farray.begin();
    std::vector<int>::iterator iter = sarray.begin();

    //farray.size() == (0 thru (num / 2))
    //sarray.size() == ((num / 2) thru num)
    for (;it != farray.end() && iter != sarray.end();) {
        if (*it > *iter) {
            final.push_back(*it);
            it++;
        }    
        else
        {
            final.push_back(*iter);
            iter++;
        }

            if (it == farray.end()) {
                for (int i = 0; iter < sarray.end(); i++) {
                    final.push_back(*iter);
                }
            }

            if (iter == sarray.end()) {
                for (int i = 0; it < farray.end(); i++) {
                    final.push_back(*iter);
                }
            }
        }

schrieb ich den merge Teil Funktion meines Mergesort, um ... na ja, damit es funktioniert. Ich habe tatsächlich einige Fragen zu diesem Code:

  1. Ist es gut in Form vergleichen gegen std :: vector :: Iteratoren es && iter für meine letzten beiden if-Anweisungen, wenn die for-Schleife sie auf ihrer nächsten Durchgang ändern könnte?
  2. Werden die Werte von iter und es auf dieser letzten Pass ändern der Schleife und meinen Code vermasseln? Wird Putting meine letzten Anweisungen aus, wenn vor dem * es und * iter Vergleich?
  3. Ist das Ende () Member-Funktion auf den letzten Wert von verweisen, was es fordert? Es scheint, wie es irgendwie vorbei verlängern könnte.

EDIT: Ich auf alle Antworten reagieren wird morgen, also schaut dann, wenn Sie mehr hören wollen. Es ist nach Mitternacht. Gute Nacht.

War es hilfreich?

Lösung

1. Es ist in Ordnung Iteratoren zu vergleichen, die für Schleifenbedingung aus dem gleichen Behälter wie einen, aber das macht nur Sinn, wenn man in der einen oder anderen Iteratoren bewegt sich entweder den Zuwachs teilweise, wenn die für die Schleifenanweisung oder im Körper der for-Schleife selbst. In dieser for-Schleife vergleichen Sie iter gegen sarray.end() aber die for-Schleife ändert sich nie iter. Das bedeutet, dass entweder es keine Wiederholungen oder die for-Schleife wird nie enden. Außerdem möchten Sie wahrscheinlich != verwenden und nicht für den Vergleich <. == und != Arbeit für alle Iteratoren < nicht.

            for (int i = 0; iter != sarray.end(); i++) {
                final.push_back(*iter);
            }

Als iter beginnt dort, wo die Schleife beginnen soll, können Sie so etwas wie dies wünschen kann:

            for (; iter != sarray.end(); ++iter) {
                final.push_back(*iter);
            }

Wie Sie noch lernen (obwohl nicht alle sind wir!), Ist es wahrscheinlich lehr durch einen Algorithmus wie dies funktioniert, aber Sie sollten sich bewusst sein, std::merge die wahrscheinlich macht, was Sie wollen.

std::merge( farray.begin(), farray.end(), sarray.begin(), sarray.end(), std::back_inserter( final ) );

(Sie müssen #include <iterator> und <algorithm>.)

2. Ich sehe nicht, Inkrementieren iter oder es in den äußeren for-Schleife for-Schleifen, die Logik in den späteren ungültig zu machen, den Punkt in 1 zur Seite.

3. end() verweist auf eine über das Ende eines Behälters, so können Sie sie für Leitungsabschluss überprüft, aber Sie sollten nicht versuchen, zu dereferenzieren einen Iterator, das „==“ auf „.end()“.

Andere Tipps

Ich habe nicht Ihre Algorithmus-Implementierung überprüfen, werde ich auf Ihre drei Fragen beziehen sich nur:

  1. Iteratoren sind ähnlich wie Zeiger auf Werte eines Behälters. Es ist genau wie size_t i und anschließend ++ i in der for-Schleife. würden Sie sich fühlen es problematisch ist Farray zu vergleichen [i] mit SFeld [i]? wahrscheinlich nicht, deshalb ist es in Ordnung.
  2. Was ich sehe, Sie in Ihrem Code zu tun hier ist, dass Sie nur die Werte lesen * it und * iter, Sie tatsächlich sie nicht ändern, deshalb werden sie nicht ändern.
  3. Das Ende () auf einen ungültigen Ort. Es zeigt nicht auf den letzten Wert, sondern „nach dem“. Es ist wie „NULL“, wenn man so will, also wenn (iter == sarray.end ()) wahr ist, werden Sie zum Absturz bringen, wenn Sie * iter schreiben, da kann man nicht dereferenzieren einen Iterator, die () bis zum Ende gleich ist.

Einige allgemeine Hinweise: Sie müssen sich über Variablennamen denken. Anrufen der Iteratoren ‚it‘ und ‚iter‘ wird Sie irgendwann verwirren. Eigentlich, wenn man genau hinschaut, hat es bereits. Wenn ‚Farray‘ und ‚SFeld‘ sind sinnvolle Namen, wie etwa ‚fite‘ und ‚siter‘.

Auch denken durch das, was die Mergesort tut. Diese letzten beiden Blöcke gibt es nur „Drain“ je nachdem, was Iterator ein paar Sachen mehr hat. So brauchen sie nicht in der ersten Schleife sein.

Ich würde wahrscheinlich schreibe es als (Pseudo-Code):

while not (list1.empty and list2.empty):
    if list1.empty:
        result.push(list2.pop)
    else if list2.empty:
        result.push(list1.pop)
    else if list1.top > list2.top:
        result.push(list2.pop)
    else:
        result.push(list1.pop)

oder in etwas rostig cargo-culted C ++:

std::vector<int>::iterator fiter = farray.begin();
std::vector<int>::iterator siter = sarray.begin();

while (fiter != farray.end() || siter != sarray.end()) {
    if (fiter == farray.end())      final.push_back(*siter++);
    else if (siter == sarray.end()) final.push_back(*fiter++);
    else if (*fiter > *siter)       final.push_back(*siter++);
    else                            final.push_back(*siter++);
}

Sie haben ein paar Dinge über hier zu denken.

Erstens, wenn Sie zwei Bereiche verschmelzen würden Sie viel besser dran mit der std :: fusionieren eher Funktion, dass Sie Ihre eigenen rollen.

Der Code ist ein wenig schwierig zu lesen, weil Sie unterschiedliche Stile für die Einrückung und wo Sie Ihre geschweiften Klammern aus. Wählen Sie einen Stil und auch daran halten.

Der erste Teil Ihrer for-Schleife scheint eine korrekte Implementierung eines merge zu sein:

for (;it != farray.end() && iter != sarray.end();) {
    if (*it > *iter) {
        final.push_back(*it);
        it++;
    }    
    else
    {
        final.push_back(*iter);
        iter++;
    }

... und dies soll alles, was Sie brauchen, um die Arbeit zu erledigen.

Der zweite Teil Ihrer Schleife hat ein paar Probleme:

   for (;it != farray.end() && iter != sarray.end();) {
         :   :
            if (it == farray.end()) {
                for (int i = 0; iter < sarray.end(); i++) {
                    final.push_back(*iter);
                }
            }

            if (iter == sarray.end()) {
                for (int i = 0; it < farray.end(); i++) {
                    final.push_back(*iter);
                }
            }
        }

Für eine Sache, die für () conditionals geschrieben werden, so dass beide it und iter darf nicht auf die end() ihrer jeweiligen Sammelstelle oder auch die Schlaufenenden. So it kann nie sarray.end() Punkt iter kann nie farray.end() zeigen und weder if Aussage kann jemals Feuer. Sie sind beide tot (nicht erreichbar) Code.

Aber selbst wenn sie nicht tot Code waren, haben sie Fehler. Die bedingte im for(...) bricht die Schleife, wenn der Iterator zeigt auf das Ende der Sammlung, aber das Iterator nie bewegt wird, so dass Sie eine unendliche Schleife haben.

Auch diese beide for(...)s sind Uneeded toten Code, weil die Iteratoren nie bis zum Ende des Vektors verweisen können.

Ein einfacher Kommentar:. Warum nicht while (condition) statt for(; !condition; ) verwenden

Diese Konstruktion ist nicht dem Standard entsprechende und schwer zu verstehen!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top