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

时间:2017-08-09 10:46:28

标签: c arrays algorithm zero

我有一个值数组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}。相反,我在以前的零位置获取垃圾值。

关于我在这里做错了什么建议?我需要其他声明吗?

11 个答案:

答案 0 :(得分:4)

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] ); //
}

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

答案 1 :(得分:3)

你应该使用单独的计数器变量,否则你将&#34;跳过&#34;分配给新数组时原始数组包含零的索引。

#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 :(得分: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 :(得分:2)

使用两个索引可以解决此问题:一个用于源阵列434 434 I MSM-irqbalance: Decided to move IRQ131 from CPU7 to CPU4 5421 5429 F libc : invalid address or address of corrupt block 0xb8f6eed8 passed to dlfree 5421 5429 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 5429 (FinalizerDaemon) 3369 3369 D powerUI : accValue============42 3369 3369 D powerUI : mCputempVlaue============42 989 3846 E IzatSvc_PassiveLocListener: E/Exiting with error virtual void izat_manager::IzatPassiveLocationListener::onLocationChanged(const izat_manager::IzatLocation*, izat_manager::IzatLocationStatus) line 113 "1" 304 304 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 304 304 F DEBUG : Build fingerprint: 'bq/Aquaris_M5/Aquaris_M5:6.0.1/MMB29M/1496676247:user/release-keys' 304 304 F DEBUG : Revision: '0' 304 304 F DEBUG : ABI: 'arm' 304 304 F DEBUG : pid: 5421, tid: 5429, name: FinalizerDaemon >>> com.vigilant.pycseca <<< 304 304 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad 304 304 F DEBUG : Abort message: 'invalid address or address of corrupt block 0xb8f6eed8 passed to dlfree' 304 304 F DEBUG : r0 00000000 r1 00000000 r2 00000000 r3 00000002 304 304 F DEBUG : r4 b8f6eed8 r5 deadbaad r6 b6d87eb8 r7 a2eae000 304 304 F DEBUG : r8 b8f6eee0 r9 b8fa3ac8 sl 2324aee0 fp 23258680 304 304 F DEBUG : ip b6d825dc sp b4162538 lr b6d54887 pc b6d54886 cpsr 60070030 304 304 F DEBUG : 304 304 F DEBUG : backtrace: 304 304 F DEBUG : #00 pc 00030886 /system/lib/libc.so (dlfree+1285) 304 304 F DEBUG : #01 pc 72b882d5 /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x1f41000) 989 6018 W ActivityManager: Force finishing activity com.vigilant.pycseca/.activities.Login 304 304 F DEBUG : 304 304 F DEBUG : Tombstone written to: /data/tombstones/tombstone_00 304 304 E DEBUG : AM write failed: Broken pipe> 304 304 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad 304 304 F DEBUG : Abort message: 'invalid address or address of corrupt block 0xb8f6eed8 passed to dlfree' 304 304 F DEBUG : r0 00000000 r1 00000000 r2 00000000 r3 00000002 304 304 F DEBUG : r4 b8f6eed8 r5 deadbaad r6 b6d87eb8 r7 a2eae000 304 304 F DEBUG : r8 b8f6eee0 r9 b8fa3ac8 sl 2324aee0 fp 23258680 304 304 F DEBUG : ip b6d825dc sp b4162538 lr b6d54887 pc b6d54886 cpsr 60070030 304 304 F DEBUG : 304 304 F DEBUG : backtrace: 304 304 F DEBUG : #00 pc 00030886 /system/lib/libc.so (dlfree+1285) 304 304 F DEBUG : #01 pc 72b882d5 /data/dalvik-cache/arm/system@framework@boot.oat (offset 0x1f41000) 989 6018 W ActivityManager: Force finishing activity com.vigilant.pycseca/.activities.Login 304 304 F DEBUG : 304 304 F DEBUG : Tombstone written to: /data/tombstones/tombstone_00 304 304 E DEBUG : AM write failed: Broken pipe ),另一个用于目标阵列x),分别为x_updi

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]; } 中的元素被复制到{{1}时,索引j仅被更新(即:加1)在x循环的每次迭代中都会更新索引x_upd

答案 4 :(得分: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]); //
}

答案 5 :(得分:2)

这种情况下的技巧是使用另一个变量来索引你的另一个数组。

所以不要这样:

x_upd[i] = x[i];

您可以使用另一个变量j,只有在为x_upd

指定值时才会增加
x_upd[j++] = x[i];

答案 6 :(得分: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,

答案 7 :(得分: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++;
  }
}

答案 8 :(得分: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]); //
}

答案 9 :(得分: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 

答案 10 :(得分: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;
}