从 C 中的数组中删除零项
Remove zero entries from an array in C
我有一个值数组 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 语句吗?
这个问题可以通过使用两个索引来解决:一个用于源数组(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
仅在 更新 (即:递增 1)时复制来自 x
的元素x_upd
,而索引 i
在 for
循环的每次迭代中更新。
这个
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]); //
}
这种情况下的诀窍是使用不同的变量索引到您的其他数组中。
所以不是这个:
x_upd[i] = x[i];
您可以有另一个变量 j
,它仅在您为 x_upd
赋值时递增
x_upd[j++] = x[i];
您应该使用单独的计数器变量,否则在分配给新数组时,您将"skip"原始数组包含零的索引。
#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;
}
无需创建新数组,查看一个数组的工作代码。
#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,
#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
您应该单独递增 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++;
}
}
您按顺序检查值 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]);
}
不需要索引
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;
}
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
或者函数可以return复制值的个数
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] ); //
}
事实上,第一个循环对应于上面显示的第二个函数实现。
问题出在这里:
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]); //
}
我有一个值数组 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 语句吗?
这个问题可以通过使用两个索引来解决:一个用于源数组(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
仅在 更新 (即:递增 1)时复制来自 x
的元素x_upd
,而索引 i
在 for
循环的每次迭代中更新。
这个
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]); //
}
这种情况下的诀窍是使用不同的变量索引到您的其他数组中。
所以不是这个:
x_upd[i] = x[i];
您可以有另一个变量 j
,它仅在您为 x_upd
x_upd[j++] = x[i];
您应该使用单独的计数器变量,否则在分配给新数组时,您将"skip"原始数组包含零的索引。
#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;
}
无需创建新数组,查看一个数组的工作代码。
#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,
#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
您应该单独递增 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++;
}
}
您按顺序检查值 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]);
}
不需要索引
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;
}
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
或者函数可以return复制值的个数
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] ); //
}
事实上,第一个循环对应于上面显示的第二个函数实现。
问题出在这里:
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]); //
}