您的位置:首页 > 其它

第五十五篇:删除一个数组中多个连续或不连续重复的数字,保留一个

2016-04-28 11:42 417 查看
在直线筛选斜率的时候,碰到了去除直线的斜率相近的问题:

程序很简单,我直接拿网上的程序:

如下:

#include "stdio.h"

//去除重复,产生新数组
int only1(int a[],int n)
{
int i,j,k;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]==a[j])
{
for(k=j;k<n-1;k++)
{
a[k]=a[k+1];
}
n--;
//	j--;    此处需要修
}
}
}
printf("\n\n清除重复数后的新数组:\n");
for(i=0;i<n-1;i++)
printf("%d  ",a[i]);
return n-1;
}
//排序
void sort(int a[],int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=i;j<n;j++)
{
if(a[i]<a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
printf("\n\n排序后的数组:\n");
for(i=0;i<n;i++)
printf("%d  ",a[i]);
}
int main()
{
int a[10]={1,2,3,7,5,6,7,7,8,16};
//  sort(a,only1(a,10));
only1(a,10);
}
运行结果:



为什么还是有重复呢?说明程序有漏洞,观察发现,

a[10]={1,2,3,7,5,6,7,7,8,16};
中连续的重复数字只删除了一个,说明只删除了部分,这是不是和数组的中重复数组的位置有关?怀疑:连续重复数字与间隔重复数字的删除对于此程序有漏洞的,实验一下,将数组中重复数字改为不连续的
a[10]={1,2,3,7,5,6,7,8,7,16};
运行:



果然,不连续的三个重复数字都删除后只保留了一个,

说明对程序的漏洞怀疑是正确的,那么在哪里改呢?

读原程序发现,a[i]与a[j]如果相同后,数组后面所有的数字都前移动一位,a[j]被删除,a[j+1]移动到a[j],而下一次再比较的时候从j+1开始,说明原数组中的a[j+1]被漏掉了,j+1开始循环是原数组的a[j+2],原来如此,找到问题后怎么解决呢?

每次找到相同的数字后,相同数字后面的所有数字前移动一位后,仍然从相同数字的位置开始循环,即删除第j个元素后,把j后面的元素前移动一位后,任然从j开始循环好了,修改程序就是:把我标记颜色屏蔽掉的加上,即把前面的双斜杠去掉,     

     即加上     j--;

a[10]={1,2,3,7,5,6,7,7,8,16}

运行结果:



问题解决!!!这样的编程漏洞是由于大多数人的逻辑思维定视

规范法编程可以避免:

int main() {
int a[] = {36,25,14,63,36,25,14,36,36};
int i,j,k,n = sizeof(a)/sizeof(a[0]);
for(i = 0; i < n; ++i)
printf("%d ",a[i]);
printf("\n");
for(i = 0; i < n; ++i) {
for(j = i + 1; j < n - 1; ++j) {
if(a[j] == a[i]) {
for(k = j; k < n - 1; ++k)
a[k] = a[k + 1];
}
--n;
}
}
for(i = 0; i < n; ++i)
printf("%d ",a[i]);
printf("\n");
return 0;
}

这里使用的是++j,这样就避免这个问题!!!


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: