简体   繁体   English

分离一个包含偶数和奇数的数组

[英]Segregating an array for even and odd numbers

I have implemented an algorithm to change an array so that all the even numbers are moved to the beginning of the array and the old numbers to the end of the array. 我已经实现了一种算法来更改数组,以便所有偶数都移到数组的开头,旧数字移到数组的结尾。 Here is my program :- 这是我的程序:

#include <iostream>
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<size) {
            l++;
        }
        while((arr[h]%2) && h >=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;
}

I don't get the expected result 我没有得到预期的结果

1 2 3 4 5 6 7 8 9 
8 2 6 5 4 3 7 1 9 

What am I missing? 我想念什么?

What you're trying to do is also called partitioning. 您尝试执行的操作也称为分区。 The standard library provides two algorithms to do just that: std::partition and std::stable_partition . 标准库提供了两种算法来做到这一点: std::partitionstd::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
}

http://ideone.com/kZI5Zh http://ideone.com/kZI5Zh

If you're still interesting in writing your own , cppreference 's description of std::partition includes the equivalent code. 如果您仍然对编写自己的内容感兴趣,则cppreferencestd::partition描述std::partition包含等效的代码。
Your version is missing an if statement right before the swap. 您的版本在交换之前丢失了if语句。 You should only swap when there is an odd on the left. 仅当左边有奇数时,才应交换。

Problem 1: 问题一:

You need to call the swap only if l has not crossed h , you are calling it always. 仅当l尚未超过h ,才需要调用swap ,而您总是在调用它。

Consider the array {2,1} , which is already sgeregated. 考虑数组{2,1} ,它已经被隔离了。
Now after the two inner while loops l will be 1 and h will be 0 . 现在,在两个内部while循环之后, l将为1h将为0 In your case you'll go ahead and swap, but a swap is not really needed since l has crossed h . 在您的情况下,您将继续进行交换,但是实际上不需要交换,因为l超过了h And when that happens the array is already segregated. 当发生这种情况时,阵列已经被隔离。

So change 所以改变

swap(arr[l], arr[h]);

to

if(l<h) {
    swap(arr[l], arr[h]);
}

Problem 2: 问题2:

Also the order of conditions in your inner while loops must be reversed. 同样,内部while循环中条件的顺序也必须颠倒。 You are checking 您正在检查

while(number at index l is even AND l is a valid index) {
    l++;
}

which is incorrect. 这是不正确的。 Consider an array {2,4} , now at some point in the above while loop l will be 2 and you go ahead and access arr[2] , which does not exist. 考虑一个数组{2,4} ,现在在上面的某个时刻,而循环l将为2 ,然后继续访问arr[2] ,该数组不存在。

What you need is: 您需要的是:

while(l is a valid index AND number at index l is even) {
    l++;
}

As simple as it gets: 变得如此简单:

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

Can't you just use standard sort? 您不能只使用标准排序吗?

Something like: 就像是:

#include <stdio.h>
#include <stdlib.h>

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM