9
votes

Trouver le mode de vecteur d'INTS en C ++

Donc, j'essaie de créer un programme de base pour apprendre les bases de C ++, je génère 100 nombres aléatoires de 0 à 100 et les stockez dans un vecteur, je affiche alors la somme, la moyenne, la médiane, le mode , haut et bas du vecteur. J'ai tout encore fait, sauf le mode qui est où je suis coincé. Voici le code que j'ai jusqu'à présent.

int modeFunction()
     {
         numMode = 0;
         count = 0;
         for (int n = 0; n < 100; n++)
         {
             for (int y = 0; y < 100; y++)
             {
                 if (numVector.at(y) == numVector.at(n))
                {
                    numMode = numVector.at(y);
                    count++;
                }
             }

         }
         return numMode;
     }


4 commentaires

Si myvector est un std :: vecteur (semble le savoir au moins), vous pouvez l'indexer comme un tableau: myvector [y] et myvector [n] donnera la même chose que la version myvector.at , mais semble plus agréable IMHO. :)


@Xeo: la différence étant que à a défini un comportement lorsque l'index est hors limites. Onguablement opérateur [] est une micro-optimisation, bien que vous dites que c'est aussi un peu de différence de style.


@Steve: Ah, merci pour cette Titre. :) N'a pas pris la peine avec à , mais un tableau normal a également un comportement indéfini pour un accès hors limites, bien qu'il soit certainement agréable d'avoir un comportement défini lorsque vous en avez besoin. :)


@Xeo: Pour être honnête, je n'utilise jamais à moi-même. Je me demande de temps en temps si je devrais, mais dans la pratique, je n'abandonnais jamais de code que je veux jeter une exception lorsque l'indice est hors limites, il ne sert donc qu'une aide de débogage, elle "devrait" ne jamais arriver. En dépit de l'appeler une micro-optimisation, c'est une quantité raisonnable de code redondant, donc à la fin si je veux vérifier les limites, je viens de passer à Python ;-)


7 Réponses :


4
votes

Depuis le mode est le numéro qui se produit le plus fréquent, vous ne devez pas modifier NumMode code> sauf si le décompte du nouveau numéro est supérieur à Nummode code> 'S.

Editer: Pour clarifier, vous devez conserver un nombre distinct pour l'élément actuel et le nombre actuel que vous pensez être le mode. Idéalement, réglage newMode code> au premier élément est une bonne approche. P>

De plus, le mode n'est pas nécessaire unique (c'est-à-dire "1 1 2 2"). Vous voudrez peut-être garder cela à l'esprit si vous vous souciez de cela. P>

newMode = element[0]
modeCount = # of occurrence of newMode

for ( i-th element from [1 to end] ) {
   tmpCount = # of occurrence of element[i]
   if tmpCount > modeCount {
     newMode = element[i]
     modeCount = tmpCount
   }
}


1 commentaires

Je suis qui a été descendue. Je l'ai fait parce que cette réponse est incomplète car elle suppose que la matrice de nombre d'occurrences des valeurs est connue, cependant, cette matrice est la plus importante ici.



1
votes

Votre algorithme est fausse - il génère le dernier numéro de la matrice car c'est tout ce que cela peut le faire. Chaque fois que le nombre d'index y correspond au nombre d'index n vous écrasez les résultats du précédent n . Puisque vous utilisez les mêmes conditions de boucle, y et n sont toujours identiques à au moins un point dans la boucle imbriquée pour chaque possible. n valeur - et vous finirez toujours avec NumMode étant numvector.at (99) .

Vous devez modifier votre algorithme pour enregistrer le comptage pour chaque index N sur le chemin (ou au moins quel index indiquer le plus grand ), afin que vous puissiez savoir à la fin de la boucle n quelle entrée a eu lieu le plus souvent.


0 commentaires

1
votes

solutions alternatives. Remarque: non testé.

int mode1(const std::vector<int>& values)
{   
    int old_mode = 0;
    int old_count = 0;
    for(size_t n=0; n < values.size(); ++n) 
    {
        int mode = values[n];
        int count = std::count(values.begin()+n+1, values.end(), mode);

        if(count > old_count) 
        {
            old_mode = mode;
            old_count = count;
        }
    }
    return old_mode;
}

int mode2(const std::vector<int>& values)
{   
    return std::max_element(values.begin(), values.end(), [](int value)
    {
        return std::count(values.begin(), values.end(), value);
    });
}


2 commentaires

Je pense que dans mode1 () Vous devez comparer compter + 1 avec old_count car vous commencez à compter à partir de la position une après la position de la valeur comptée : c.-à-d. Vous devez ajouter le premier à compter .


De plus, je pense que ce n'est pas une bonne pratique d'attribuer la valeur initiale de la valeur avec la propriété recherchée sous la forme 0 . Il devrait être préférable d'utiliser le premier élément à cette fin.



0
votes

Mode signifie un nombre avec la fréquence la plus élevée. La logique devrait être - xxx


1 commentaires

@Cistoran - La logique peut être encore meilleure amélioration de l'efficacité, mais c'est ce que l'algorithme doit être en fonction de votre processus de pensée.



11
votes

Étant donné que toutes les valeurs sont comprises entre 0 et 100, vous pouvez trouver le mode efficacement avec un histogramme: xxx


1 commentaires

Cela ne fonctionnerait-il pas aux valeurs en dehors de [0,100] (cela devrait fonctionner pour tout histogramme symétrique, non?)



3
votes

L'approche de BMCnett fonctionne bien si nombre d'éléments sont suffisamment petits. Si vous avez un grand nombre d'éléments, mais la valeur de toutes les valeurs d'élément est avec une petite plage à l'aide de la carte / HASHMAP fonctionne bien. Quelque chose comme xxx


0 commentaires

0
votes
    int number = array_list[0];
    int mode = number;
    int count = 1;
    int countMode = 1;

    for (int i=1; i<size_of_list; i++)
    {
          if (array_list[i] == number) 
          { // count occurrences of the current number
             count++;
             if (count > countMode) 
                {
                      countMode = count; // mode is the biggest ocurrences
                      mode = number;
                }
          }
          else
          { // now this is a different number
                if (count > countMode) 
                {
                      countMode = count; // mode is the biggest ocurrences
                      mode = number;
                }
               count = 1; // reset count for the new number
               number = array_list[i];
      }
    }

0 commentaires