我有一个值数组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}
。相反,我在以前的零位置获取垃圾值。
关于我在这里做错了什么建议?我需要其他声明吗?
答案 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_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];
}
中的元素被复制到{{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;
}