与我之前的问题类似,这次我试图打印不会出现两次或两次以上的数字。
这是我的代码:
#include <stdio.h>
int main()
{
int i;
int a[10]={2,2,2,4,6,6,9,10,10,11};
for(i=0; i < 10; ++i)
{
if(a[i] != a[i+1] && i!=9)
{ if(i > 0 && a[i] != a[i-1])
printf("%d ",a[i]);
}
if(i==9 && a[i]!=a[i-1])
printf("%d", a[i]);
}
printf("\n");
return 0;
}
输出结果是正确的,即4,9,11,但我需要分别考虑i的最终值。还有更好的方法吗?
答案 0 :(得分:2)
请注意,逻辑运算符具有优先权,并且在优先级相同的情况下,如在if
语句中,它们从左到右进行计算。所以
if(a[i] != a[i+1] && i!=9)
将在a[10]
之前评估i!=9
,导致超出读取范围。如果您将其更改为
if(i!=9 && a[i] != a[i+1])
问题不会发生,因为i!=9
之前被评估过,并且因为它将是假的,所以其余部分都是假的而不是被评估,没有出界读。
更好的是,循环i=0; i<9
并在循环外移动第二个,从而无需完全检查i!=9
。
此外,对于数组{2,3,.....}
,代码将失败,它将不会打印第一个元素
正如它应该。
以下是代码的更好版本
#include <stdio.h>
int main()
{
int i;
int a[10]={2,2,2,4,6,6,9,10,10,11};
for(i=0; i < 9; ++i)
{
if(a[i] != a[i+1])
{
if(i == 0 || a[i] != a[i-1])
printf("%d ",a[i]);
}
}
if(a[8] != a[9])
printf("%d", a[9]);
printf("\n");
return 0;
}
请注意,在循环之后,我们只需使用正确的下标。效率更高,因为添加ifs
来检查最后一个元素将在每次迭代时评估ifs
,而现在只评估一次。
希望有所帮助
答案 1 :(得分:1)
您始终可以使用嵌套for循环来检查值。这种方式也适用于未排序的列表。
int i;
int j;
int match;
for (i = 0; i < 10; i++)
{
match = 0;
for(j = 0; j < 10; j++)
{
if (a[i] == a[j] && i!=j)
match = 1;
break;
}
if (match == 0)
printf("%d",a[i]);
}
此代码将根据所有其他值检查每个值,并根据您的示例打印仅在列表中找到的数字。
答案 2 :(得分:0)
你只需要在for循环中检查i的值是否超出数组绑定
我认为这应该有用
int main()
{
int i;
int a[10]={2,2,2,4,6,6,9,10,10,11};
for(i=0; i < 10; ++i)
{
if(a[i] != a[(i+1)%10])
{ if(i > 0 && a[i] != a[i-1])
printf("%d ",a[i]);
}
}
printf("\n");
return 0;
}
答案 3 :(得分:0)
接受回答后
在排序数组上查找唯一值的简化方法。
#include <stdio.h>
int main() {
int a[] = { 2, 2, 2, 4, 6, 6, 9, 10, 10, 11 };
size_t n = sizeof a / sizeof a[0];
int previous = ~a[0];
size_t i;
for (i = 0; i < n; i++) {
if (a[i] != previous)
printf("%d ", a[i]);
previous = a[i];
}
printf("\n");
return 0;
}