第五十五篇:删除一个数组中多个连续或不连续重复的数字,保留一个
2016-04-28 11:42
417 查看
在直线筛选斜率的时候,碰到了去除直线的斜率相近的问题:
程序很简单,我直接拿网上的程序:
如下:
为什么还是有重复呢?说明程序有漏洞,观察发现,
果然,不连续的三个重复数字都删除后只保留了一个,
说明对程序的漏洞怀疑是正确的,那么在哪里改呢?
读原程序发现,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,这样就避免这个问题!!!
程序很简单,我直接拿网上的程序:
如下:
#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,这样就避免这个问题!!!
相关文章推荐
- 在Win7系统上利用光盘启动盘安装Ubuntu 14.04(双系统、各自独立)
- vtk实战(十九)——读取 PDB数据
- Macosx 安装 ionic 成功教程
- 图解CSS中position属性的定位用法
- limits.conf配置详解
- vlc-android(1.9.1) 移到android studio
- 用dos命令实现导入、导出windows计划任务详解
- 自定义App头像背景圆框
- Material Design: NavigationView FlaotingActionBar SnackBar的使用,navigationview
- vtk实战(十六)——解析STL文件
- ZeroMQ研究与应用分析
- Caused by: android.content.res.Resources$NotFoundException: File res/drawable/main_tab_conversation_
- 目标检测“Exploit All the Layers: Fast and Accurate CNN Object Detector with Scale Dependent Pooling and”
- [openvc]4.创建一张图片并保存到本地
- php开启openssl的方法
- firstobjet free xml的格式化
- 磊科路由器动态获取IP模式下不显示DNS设置的问题
- 从java到初学javaweb,所遇问题
- 构造函数&拷贝构造函数&赋值构造函数
- UI测试导入Espresso时的冲突