Question

Sans doute certains d'entre vous ont vu mon affectation récente, tout ce qui concerne le même programme. Je continue à avoir des problèmes avec elle. Je le répète: encore l'apprentissage, pas très avancé, ne comprennent pas des pointeurs très bien, ne pas prendre une classe, ne comprennent pas les concepts OOP du tout, etc. Ce code se confond juste deux vecteurs, triés FARRAY et sarray, en un seul trié vecteur. Au moins, j'espère que ce qu'il fait. Dites-moi:

    //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);
                }
            }
        }

Je réécris la partie de fusion de ma fonction de tri de fusion pour ... eh bien, le faire fonctionner. J'ai en fait plusieurs questions sur ce code:

  1. Est-il de bon à comparer std :: vector :: itérateurs il iter && pour mon dernier deux instructions if si la boucle pourrait les changer sur son passage suivant?
  2. Est-ce que les valeurs de iter et il changer le dernier passage et bousiller mon code de cette boucle? Est-ce que mettre mon dernier si les déclarations avant le * et * comparaison iter?
  3. ne se réfère à la dernière valeur de la fonction de l'élément d'extrémité () de tout ce qui est l'appeler? Il semble que cela pourrait étendre au-delà en quelque sorte.

EDIT: Je répondrai à toutes les réponses demain, alors revenez alors si vous voulez en savoir plus. Il est minuit passé. Bonne nuit.

Était-ce utile?

La solution

1. Il est bien de comparer les itérateurs qui sont du même conteneur comme pour condition de la boucle, mais cela n'a de sens que si vous déplacez un ou l'autre itérateurs soit la partie de l'incrément si l'instruction for boucle ou dans le corps de la boucle elle-même. Dans cette boucle vous comparez iter contre sarray.end() mais la boucle ne change jamais iter. Cela signifie que soit il n'y aura pas d'itérations ou la boucle ne sera jamais fin. , Vous voulez probablement utiliser != et non < pour la comparaison. travail == et != pour tous les itérateurs, < ne fonctionne pas.

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

démarre iter où vous voulez que la boucle commence, vous voudrez peut-être quelque chose comme ceci:

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

Comme vous apprenez toujours (même si nous ne sommes pas tous!), Il est probablement intéressant de travailler à travers un algorithme comme celui-ci, mais vous devez être au courant std::merge qui demande probablement ce que vous voulez.

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

(Vous devez #include <iterator> et <algorithm>.)

2. Je ne vois pas incrémenter iter ou dans la partie extérieure de la boucle la logique invalidant la plus tardive pour les boucles, le point 1. de côté.

3. points de end() à un après la fin d'un conteneur, de sorte que vous pouvez l'utiliser pour les contrôles de terminaison de boucle, mais vous ne devriez pas essayer de déréférencer un itérateur qui est « == » à « .end() ».

Autres conseils

Je n'ai pas vérifié la mise en œuvre de votre algorithme, je vais juste faire référence à vos trois questions:

  1. itérateurs sont beaucoup comme des pointeurs vers des valeurs d'un conteneur. Il est exactement comme l'utilisation size_t i puis ++ i dans la boucle. vous sentiriez-vous qu'il est difficile de comparer farray [i] avec sarray [i]? probablement pas, donc il est OK.
  2. Ce que je vois que vous faites dans votre code ici, est que vous venez de lire les valeurs de * et * iter, vous ne donc pas les changer en fait, ils ne changeront pas.
  3. Les points fin () à un endroit non valide. Il ne pointe pas à la dernière valeur, mais « après ». Il est comme « NULL » si vous voulez, par conséquent, si (iter == sarray.end ()) est vrai, vous brisez si vous écrirez * iter, parce que vous ne pouvez pas déréférencer un itérateur qui est égale à la fin ().

Quelques conseils généraux: Vous devez penser à des noms de variables. Appel des itérateurs « il » et « iter » va vous confondre à un moment donné. En fait, si vous regardez attentivement, il a déjà. Si « farray » et « sarray » sont des noms significatifs, sur la façon dont « fiter » et « siter ».

En outre, réfléchir à ce que le genre de fusion est en train de faire. Ces deux derniers blocs sont là juste pour « vider » selon iterator a des choses à gauche. Donc, ils ne doivent pas nécessairement être dans la première boucle.

Je serais probablement écrire comme (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)

Ou dans le fret-culted un peu rouillé 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++);
}

Vous avez quelques choses à penser ici.

Tout d'abord, si vous fusionnez deux gammes vous seriez beaucoup mieux en utilisant le std :: fusion fonction plutôt que vos propres modèles.

Votre code est un peu difficile à lire parce que vous utilisez des styles différents pour l'indentation et où vous vos accolades. Choisissez un style et de s'y tenir.

La première partie de votre boucle semble être une bonne mise en œuvre d'une fusion:

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

... et cela devrait être tout ce que vous devez faire le travail.

La deuxième partie de la boucle a un problème de couple:

   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);
                }
            }
        }

D'une part, les pour conditionals () sont écrits de telle sorte que les deux it et iter ne doivent pas pointer vers le end() de leur collection respective, ou bien les extrémités de la boucle. Alors it ne peut jamais pointer vers sarray.end(), iter ne peut jamais pointer vers farray.end(), ni déclaration de if ne peut jamais le feu. Ils sont à la fois le code mort (injoignable).

Mais même si elles ne sont pas du code mort, ils ont des bugs. Le conditionnel dans le for(...) rompt la boucle lorsque les points de iterator à la fin de la collection, mais ce iterator est jamais déplacé, de sorte que vous avez une boucle infinie.

Encore une fois ces deux for(...)s sont uneeded code mort parce que les itérateurs ne peuvent jamais pointer vers la fin du vecteur.

Un simple commentaire. Pourquoi ne pas utiliser while (condition) au lieu de for(; !condition; )

La dernière construction est non standard et difficile à comprendre!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top