web-dev-qa-db-fra.com

C++: méthode la plus rapide pour vérifier si tous les éléments du tableau sont égaux

Quelle est la méthode la plus rapide pour vérifier si tous les éléments d'un tableau (un tableau entier préférable) sont égaux. Jusqu'à présent, j'utilisais le code suivant:

bool check(int array[], int n)
{   
    bool flag = 0;

    for(int i = 0; i < n - 1; i++)      
    {         
        if(array[i] != array[i + 1])
            flag = 1;
    }

    return flag;
}
17
Harish Vishwakarma
int check(const int a[], int n)
{   
    while(--n>0 && a[n]==a[0]);
    return n!=0;
}
22
CubeSchrauber

Voici une solution solide qui est valide C++ 11 . Les avantages sont que vous n'avez pas besoin de jouer manuellement avec les index ou les itérateurs. C'est une bonne pratique de 

préfère les appels d'algorithmes aux boucles manuscrites [Herb Sutter - Normes de codage C++]

Je pense que cela sera tout aussi efficace que la solution de Paul R.

bool check(const int a[], int n)
{
      return !std::all_of(a, a+n, [a](int x){ return x==a[0]; });
}
12
Gabor Marton

Une fois que vous avez trouvé un élément incompatible, vous pouvez sortir de la boucle:

bool check(const int array[], int n)
{   
    for (int i = 0; i < n - 1; i++)      
    {         
        if (array[i] != array[i + 1])
            return true;
    }
    return false;
}

Si cela est critique en termes de performances, il peut être optimisé légèrement de la manière suivante:

bool check(const int array[], int n)
{   
    const int a0 = array[0];

    for (int i = 1; i < n; i++)      
    {         
        if (array[i] != a0)
            return true;
    }
    return false;
}
10
Paul R

Refaites le tableau en un type de données plus grand. Par exemple, opérez sur des bits de 64 bits ou utilisez SSE ou AVX intrinsics pour un fonctionnement sur 128 ou 256 bits. Par exemple, le composant intrinsèque SSE2 est _mm_cmpeq_epi32, dont vous utiliserez le résultat avec _mm_or_si128. Vérifiez le résultat en appliquant plusieurs fois _mm_srli_si128 et _mm_cvtsi128_si32. Vérifiez le résultat toutes les quelques centaines d'itérations pour une sortie anticipée.

Assurez-vous de bien utiliser la mémoire alignée, vérifiez le début et la fin non alignés, puis le premier élément compressé avec lui-même.

4
Aleksandr Dubinsky

Recherchez une bibliothèque disponible sur votre plate-forme qui prend en charge les boucles de threading ou parallèle-for, et divisez le calcul de manière à ce que différents cœurs testent différentes plages du tableau.

Certaines bibliothèques disponibles sont répertoriées ici:

http://parallel-for.sourceforge.net/parallelfor.html

Ou éventuellement, vous pouvez utiliser le parallélisme offert par de nombreux GPU.

0
Scott Langham

Pour l'efficacité du programmeur, vous pouvez essayer les éléments suivants sur une seule ligne.

vector<int> v{1, 1, 1, 1};
all_of(v.cbegin(), v.cend(), [&r=v[0]](int value){ return value == r; }->bool);

Je n'ai pas testé exécuter ce code, laissez-moi savoir s'il y a une erreur de syntaxe.

0
Kemin Zhou

En gros, il s’agit d’une opération O(n). Vous ne pouvez donc pas faire mieux que ce que vous avez fait, à part vous passer du drapeau et de return false; lors du premier échec et de return true; après l’itération.

0
Anders R. Bystrup
bool check(int array[],int n)
{       
  // here 1st element is checked with others. This decreases the number of iteration by 1.
  // also it returns immediately. 
  // The requirement is to check if all the elements are equal. 
  // So if 1st element is equal to others then all elements are equal. 
  // Otherwise the  elements are not equal.
  for(int i=1;i<n;i++)      
  {         
    if(array[0]!=array[i])
      return false;
  }        
  return true;
}
0
Narendra

En théorie, je proposerais ceci:

bool check_single(const int a[], int n)
{
    for (int i = 1; i < n; ++i) {
        if (a[0] != a[n]) { return false; }
    }
    return true;
}

Comparé à d'autres versions (déjà proposées):

  • a[0] sera hissé à l'extérieur de la boucle par le compilateur, ce qui signifie un seul accès à un tableau dans la boucle
  • nous passons de 0 à n, ce qui est mieux (en termes d’accès) que de charger a[0] et de boucler à partir de a[n]

Evidemment, il vérifie toujours N éléments et est donc O (N).

0
Matthieu M.