J’ai implémenté un algorithme pour changer un tableau de sorte que tous les nombres pairs soient déplacés au début du tableau et les anciens numéros à la fin du tableau. Voici mon programme: –
#include using namespace std; void print(int arr[], int size) { for(int i=0;i<size;i++) { cout<<arr[i]<<" "; } cout<<endl; } void segregate(int arr[], int size) { int l=0, h=size-1; while(l<h) { while(!(arr[l]%2) && l=0) { h--; } swap(arr[l], arr[h]); } } int main() { int arr[] = {1,2,3,4,5,6,7,8,9}; int size = 9; print(arr,size); segregate(arr,size); print(arr,size); return 0; }
Je n’obtiens pas le résultat attendu
1 2 3 4 5 6 7 8 9 8 2 6 5 4 3 7 1 9
Qu’est-ce que je rate?
Ce que vous essayez de faire s’appelle également le partitionnement. La bibliothèque standard fournit deux algorithmes pour faire exactement cela: std::partition
et std::stable_partition
.
int main() { int arr[] = {1,2,3,4,5,6,7,8,9}; auto split = std::partition( std::begin(arr), std::end( arr ), []( int a ) { return ! a%2; } ); // [ begin, split ) are all even // [ split, end ) are all odd }
Si vous êtes toujours intéressé par l’ écriture de votre propre , la description de std::partition
cppreference inclut le code équivalent.
Il manque à votre version une instruction if
juste avant l’échange. Vous ne devriez échanger que lorsqu’il y a un impair à gauche.
Problème 1:
Vous devez appeler le swap
uniquement si l
n’a pas franchi h
, vous l’appelez toujours.
Considérez le tableau {2,1}
qui est déjà sgeregated.
Maintenant, après les deux boucles while internes, l
sera 1
et h
sera 0
. Dans votre cas, vous allez procéder à un échange, mais un échange n’est pas vraiment nécessaire, car l
franchi h
. Et lorsque cela se produit, le tableau est déjà séparé.
Alors change
swap(arr[l], arr[h]);
à
if(l
Problème 2:
De plus, l'ordre des conditions dans vos boucles while internes doit être inversé. Vous vérifiez
while(number at index l is even AND l is a valid index) { l++; }
ce qui est incorrect. Considérons un tableau {2,4}
, à un moment donné de ce qui précède, alors que la boucle l
sera 2
et que vous continuez et accédez à arr[2]
, qui n'existe pas.
Ce dont vous avez besoin c'est:
while(l is a valid index AND number at index l is even) { l++; }
Aussi simple que cela devient:
void partitionEvenOdd(int array[], int arrayLength, int &firstOdd) { firstOdd = 0; for (int i = 0; i < arrayLength; i++) { if (array[i]%2 == 0) { swap(array[firstOdd], array[i]); firstOdd++; } } }
Ne pouvez-vous pas simplement utiliser le sorting standard?
Quelque chose comme:
#include #include int values[] = { 40, 10, 100, 90, 20, 25 }; int compare (const void * a, const void * b) { // return -1 a-even and b-odd // 0 both even or both odd // 1 b-even and a-odd } qsort (values, 6, sizeof(int), compare);