从 C 中的数组中删除零个条目

问题描述 投票:0回答:12

我有一个值数组

x = {0,0,1,2,3,0,0,7,8}
,我想使用 C 删除零条目。

尝试:

我试图循环遍历数组中的每个值并检查该条目是否不等于零。如果这个条件成立,那么我将尝试使用原始数组值填充新数组。

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

int main() {
    int x[] = { 0, 0, 1, 2, 3, 0, 0, 7, 8 };
    int i;
    int x_upd[100];
    for (i = 0; i < 9; i++) {
        if (x[i] != 0) {
            x_upd[i] = x[i]; // if true, populate new array with value
        }
    }
    for (i = 0; i < 9; i++) {
        printf(" Peak updated %d\t", x_upd[i]); //
    }
    return 0;
}

输出没有给我所需的值

{1,2,3,7,8}
。相反,我在零曾经所在的位置得到了垃圾值。

对我在这里做错了什么有什么建议吗?我需要 else 语句吗?

c arrays algorithm zero
12个回答
5
投票

C++中已经有这样的函数了。它被命名为

remove_copy
。在 C 中,这样的函数可以如下所示,如下面的演示程序所示。

#include <stdio.h>

int * remove_copy(const int *in, size_t n, int *out, int value)
{
    for (size_t i = 0; i != n; i++)
    {
        if (in[i] != value) *out++ = in[i];
    }

    return out;
}

int main( void )
{
    int a[] = { 0, 0, 1, 2, 3, 0, 0, 7, 8 };
    int b[sizeof(a) / sizeof(*a)];
    const size_t N = sizeof(a) / sizeof(*a);

    int *last = remove_copy(a, N, b, 0);

    for (int *first = b; first != last; ++first)
    {
        printf("%d ", *first);
    }

    putchar('\n');

    return 0;
}

程序输出为

1 2 3 7 8

或者函数可以返回复制值的数量

size_t remove_copy(const int *in, size_t n, int *out, int value)
{
    size_t m = 0;

    for (size_t i = 0; i != n; i++)
    {
        if (in[i] != value) out[m++] = in[i];
    }

    return m;
}

对于您的代码,您需要使用一个附加变量来将索引保留在目标数组中。例如

int m = 0;

for ( i = 0; i < sizeof( x ) / sizeof( *x ); i++ )
{
    if ( x[i] != 0 )
    {
        x_upd[m++] = x[i]; // if true, populate new array with value
    }
}

for ( i = 0; i < m; i++ )
{
    printf(" Peak updated %d\t", x_upd[i] ); //
}

事实上,第一个循环对应于上面所示的第二个函数实现。


3
投票

您按顺序浏览 0-9 一次值,然后跳过

0
的值,因此得到
{garbage, garbage, 1, 2, 3, garbage, garbage, 7, 8}
。您必须为非
0
:

的值的数量保留一个单独的计数器
int position = 0;
for(i = 0; i < 9; i++)
{
    if(x[i] != 0)
    {
        x_upd[position] = x[i]; // if true, populate new array with value
        position++;
    }
}

//loop until you get to counter
for(i = 0; i < position; i++)
{
    printf(" Peak updated %d\t", x_upd[i]); 
}

3
投票

您应该使用单独的计数器变量,否则在分配给新数组时,您将“跳过”原始数组包含零的索引。

#include <stdio.h>

int main() {
    int x[] = { 0, 0, 1, 2, 3, 0, 0, 7, 8 };
    int i;
    int j = 0;
    int x_upd[100];
    for (i = 0; i < 9; i++) {
        if (x[i] != 0) {
            x_upd[j++] = x[i]; // if true, populate new array with value
        }
    }
    for (i = 0; i < j; i++) {
          printf(" Peak updated %d\t", x_upd[i]); //
    }
    return 0;
}

2
投票

这种情况下的技巧是使用不同的变量来索引到其他数组。

所以代替这个:

x_upd[i] = x[i];

您可以有另一个变量

j
,仅当您为
x_upd

赋值时才会递增
x_upd[j++] = x[i];

2
投票

无需创建新数组,请参阅使用一个数组的工作代码。

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

int main()
{
    int x[] = { 0, 0, 1, 2, 3, 0, 0, 7, 8 };
    int i, n;

    for (i = 0, n = 0; i<9; i++)
    {
        if (x[i] != 0)
        {
            x[n++] = x[i];
        }
    }

    for (i = 0; i<n; i++)
    {
        printf("%d,", x[i]);
    }
    return 0;
}

输出:

1,2,3,7,8,

2
投票

这个

for(i=0;i<9;i++)
{
  if(x[i] != 0)
  {
      x_upd[i] = x[i]; // if true, populate new array with value
  }
}

正在跳过

x_upd
数组中的位置,因为即使您不在新数组中插入值,
i
仍然会递增。

你应该这样做:

int j = 0;
for(i=0;i<9;i++)
{
  if(x[i] != 0)
  {
      x_upd[j++] = x[i]; // if true, populate new array with value
  }
}

那么,这里

for(i=0;i<9;i++)
{
  printf(" Peak updated %d\t",x_upd[i]); //
}

你应该数到

j
:

for(i=0;i<j;i++)
{
  printf(" Peak updated %d\t",x_upd[i]); //
}

2
投票

这个问题可以通过使用两个索引来解决:一个用于源数组

x
),另一个用于目标数组
x_upd
),分别是
i
j
,在下面的代码中。

int i, j;
for(i=0,j=0; i<9; i++) {
  if (!x[i]) // is x[i] zero?
     continue; // then skip this element

  // otherwise copy current element and update destination index
  x_upd[j++] = x[i];       
}

正如您所看到的,当

j
中的元素被复制到 x 时,索引
x_upd
才会被
updated
(即:增加 1),而索引
i
在每个元素中都会被更新。
for
循环的迭代。


2
投票

问题就出在这里:

for(i=0;i<9;i++)
{
  if(x[i] != 0)
  {
      x_upd[i] = x[i]; // if true, populate new array with value
  }
}

for(i=0;i<9;i++) {
   printf(" Peak updated %d\t",x_upd[i]); //
}

您需要为 x 和 x_upd 维护单独的索引,因为它们的大小不同(x_upd 不会有“0”)。

试试这个:

int j;
for(i=0,j=0;i<9;i++) {
  if(x[i] != 0)
  {
      x_upd[j] = x[i]; // if true, populate new array with value
      j++;             // index for values inserted 

  }
}

要打印,请使用从上述代码获得的正确计数:

int k;
for(k=0;k<=j;k++) {
   printf(" Peak updated %d\t",x_upd[k]); //
}

2
投票

您应该单独增加 x_upd 数组索引。比如:

int y = 0;
for(i=0;i<9;i++)
{
  if(x[i] != 0)
  {
      x_upd[y] = x[i]; // if true, populate new array with value
      y++;
  }
}

1
投票
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
int x[] = {0,0,1,2,3,0,0,7,8};
int i;
int count = 0;
int x_upd[100];
for(i=0;i<9;i++)
    {
      if(x[i] != 0)
      {
          x_upd[count] = x[i]; // if true, populate new array with value
          count++;
      }
    }

for(i=0;i<count;i++)
    {
      printf(" Peak updated %d\t",x_upd[i]); //
    }
return 0;
}

输出

Peak updated 1  Peak updated 2  Peak updated 3  Peak updated 7  Peak updated 8 

1
投票

无需索引

int populate(int *src, int *dest, int size)
//usage: - src - source table
//src - source table
//dest - destination table
//size of the source table - source table
//Return: -1 if pointers are null, -2 if source table has zero elements, or number of non zero elements copied
{
    int result = (src == NULL || dest == NULL) * -1;
    // it an equivalen of:
    // int result;    
    // if(src == NULL || dest == NULL)
    //     result = -1;
    // else
    //     result = 0;
    if(size == 0) result = -2;
    if (!result)
    {
        while(size--)
            if (*src)
            {
                *dest++ = *src;
                result++;
            }
        src++;
    }
    return result;
}



int main()
{
    int x[] = { 0,0,1,2,3,0,0,7,8 };
    int x_upd[100];

    int result = populate(x,x_upd, sizeof(x) / sizeof(x[0]))
    for (int i = 0; i<result; i++)
    {
        printf(" Peak updated %d\t", x_upd[i]); //
    }
    return 0;
}

0
投票

首先,我们必须知道数组中“第一个非零”值的索引:

idx = 0;
while((idx < arrySize) & (arry[idx] == 0)) idx++;

从这里我们可以:

--在涉及数组的后续循环中将 idx 视为“零”...或者

--构造一个新数组,仅保存旧数组的有效元素:

for(j=0; j<arrySize-idx; j++) newarry[j] = arry[j+idx];

.

© www.soinside.com 2019 - 2024. All rights reserved.