将所有零移动到数组的开头

时间:2015-03-21 18:55:20

标签: c arrays

我正在尝试编写一个函数,将所有数字从数组的开头移动到结尾。订单不应该改变。

例如我有这个数组:

1,2,3,4,5,0,0,0,0

我想将其更改为:

0,0,0,0,1,2,3,4,5

我已经写了一个版本,但它无法保留订单。 (array []是原始的,[]是排序的)

#include <stdio.h>
#define SIZE_MAX 20

int main()
{
    int array[SIZE_MAX] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
    int a[SIZE_MAX];
    int i;
    int p = 0;

    for (i = SIZE_MAX-1; i >= 0; i--, p++)
    {
        a[i] = array[p];
    }

    for (i = 0; i < SIZE_MAX; i++)
    {
        printf("%d", a[i]);
    }
}

6 个答案:

答案 0 :(得分:4)

一种选择是循环遍历数组两次,首先复制零,然后复制其余值:

#include <stdio.h>
#define SIZE_MAX 10

int main()
{
    int array[SIZE_MAX] = {1, 2, 0, 0, 3, 4, 5, 0, 0, 0};
    int a[SIZE_MAX];
    int i;
    int p = 0;

    for (i = 0; i < SIZE_MAX; ++i) {
        if (array[i] == 0) {
            a[p++] = 0;
        }
    }

    for (i = 0; i < SIZE_MAX; ++i) {
        if (array[i] != 0) {
            a[p++] = array[i];
        }
    }

    for (i = 0; i < SIZE_MAX; i++) {
        printf("%d", a[i]);
    }
}

我将SIZE_MAX更改为10,以便它与数组中的元素数相匹配。

答案 1 :(得分:3)

如果你需要在开头的所有0和其他数字相同的顺序尝试这个:

#include <stdio.h>
#define SIZE_MAX 9

int main()
{
    int array[SIZE_MAX] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
    int a[SIZE_MAX];
    int i;
    int temp[SIZE_MAX];
    int ind1=0,ind2=0;

    // separating all the 0's and store it at the beginning
    for (i = 0; i < SIZE_MAX; i++)
    {
        if(array[i]==0)
          a[ind1++]=0;
        else
          temp[ind2++]=array[i];
    }

    // storing rest of the numbers in order
    for (i = 0; i < ind2; i++)
    {
        a[ind1++]=temp[i];
    }

    for (i = 0; i < SIZE_MAX; i++)
    {
        printf("%d", a[i]);
    }
}

注意:
首先我将所有0存储在结果数组中,同时所有非零值都存储在temp数组中。
之后,我刚刚将temp数组合并到结果数组中。

答案 2 :(得分:3)

句子“我正在尝试编写一个函数,它将所有数字从数组的开头移动到它的结尾。”听起来应该在适当的地方完成 - 事实证明这个问题很容易做到就地算法。请注意,与此处的其他算法不同,这只扫描数组一次,并将数组写入一次。在这里,我把它写成了一个函数:

void relocate_zeroes(size_t length, int *array) {
    int *target = array + length - 1;
    int *source = target;

    for (; source >= array; source--) {
        if (*source) {
            *target-- = *source;
        }
    }

    while (target >= array) {
        *target-- = 0;
    }
}

基本上我们从头到尾扫描一次源数组;如果我们遇到一个非零整数,我们将它重新定位在前一个非零整数之前。扫描完整个数组后,基数(array)和target之间的区域将填充零。

在开始时,targetsource都指向数组的最后一个值;如果*source不为0,我们会将*target替换为*source;也就是说,如果最后一个元素不为零,我们自己替换它并减少targetsource指针;如果最后一个元素为0,我们不会将其复制到任何地方,只会减少source指针;最后我们以这种方式继续复制了所有非零元素,我们可以用零填充剩余的数组元素。

鉴于计划:

#define SIZE_MAX  9

int main() {
    int array[SIZE_MAX] = {1, 0, 2, 3, 0, 4, 0, 0, 5};
    int i;

    relocate_zeroes(SIZE_MAX, array);

    for (i = 0; i < SIZE_MAX; i++) {
        printf("%d ", array[i]);
    }
}

输出

0 0 0 0 1 2 3 4 5

如果2阵列版本需要,那么这也很容易修改:

void relocate_zeroes(size_t length, int *source_array, int *target_array) {
    int *target = target_array + length - 1;
    int *source = source_array + length - 1;

    for (; source >= source_array; source--) {
        if (*source) {
            *target-- = *source;
        }
    }

    while (target >= target_array) {
        *target-- = 0;
    }
}

答案 3 :(得分:1)

整数 fullArray[] = { 1, 10, 20, 0, 59, 63, 0, 88, 0 };

    for (int i = 0; i <= fullArray.length - 1; i++) {

        if (fullArray[i] == 0 && i > 0) {

            int temp = fullArray[i - 1];
            if (temp != 0) {
                fullArray[i - 1] = 0;
                fullArray[i] = temp;
                
                i = -1;

            }

        }

    }
    System.out.println(Arrays.asList(fullArray).toString());

答案 4 :(得分:0)

这是使用swap()

的就地方法
#include <stdio.h>
#define SIZE_MAX 20

swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

moveZerosLeft(int length, int *array)
{
    int i = 0;
    int cur = length - 1;
    for( i = length - 1; i >= 0; --i)
        if(array[i] != 0) 
        {
            swap(&array[i], &array[cur--]);
        }   
}

int main()
{
    int array[SIZE_MAX] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
    int i;
    int length = 9;

    moveZerosLeft(length, array);

    // display the result
    for(i = 0; i < length; i++)
    {
        printf("%d ", array[i]);
    }
}

我们从阵列的右侧扫描到左侧。当我们看到一个非零值时,我们将它与我们之前看到的零交换。

此方法只需要扫描一次数组。

答案 5 :(得分:0)

public class Demo{

public static void moveZeros() {
    int[] num = {1, 0, 0 , 6, 7, 0};
    int temp=-1;
    for (int i = 0; i < num.length;i++)
    {
        if(num[i]!=0)
        {
           ++temp;
           if(num[temp] ==0){
               int val = num[i];
               num[i]=num[temp];
               num[temp]=val;
           }
           else
           {
               num[temp]=num[i];
           }
       }

    }
}
public static void main(String args[])
{
    Demo.moveZeros();
}

}