一、题目描述
我们先来具体描述一下题目所表达的意思:你首先在键盘上输入一个数字,这个数字就是你要输入数字的个数。然后输入一组数据,把这组数据保留在一个数组当中。最后查重,删除掉多次出现多余的数值,最终输出的结果是所有重复的数字只保留第一次出现的那份。
二、思路讲解
一共写出来四组代码,经过不断的思考,代码是越来越简单。但是前三组的代码思路基本上是相同的,只不过是代码优化了。第四组是另一种思路,也是运行效率最高的一种。
下面是第一组:
这种代码是先把整个数据输入其中。然后再一一查询。
#include<stdio.h> #define N 100 int main() { int n, i, k, j; int arr[N]; scanf("%d", &n); for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } for (i = 0; i < n; i++) //遍历整个数组的数字 { for (j = i ; j < n; j++) //从当前数字开始与剩余的数字进行比较 { if (arr[j] == arr[i]) //判断之后的数字是否与当前相等 { for (k = j; k < n - 1; k++) //找到相等的数字后,需要所有的数字前移一位 { arr[k] = arr[k + 1]; } n--; //因前移一位,数组的整数个数减一 j--; //因循环玩后要执行j++,会跳到下一个数字与剩余的数字比较。但是注意,当前 //的j并没有查找结束,前移一位后面还可能有相同的,需要j--后再j++,相当于 //还是当前j的位置。 } } printf("%d ", arr[i]); //直接打印数组 } return 0; }
下面是第二组:
写完第一组代码后,虽然思路是正确的,但是确实运行效率不高,代码较乱、较麻烦、不易理解。于是就开始优化代码。第一组是每个数字都要与后面的比较,效率太低。于是就想到了输入一个,就与前面的比较看是否有重复。相对于第一组的代码,这组的代码是一个一个输入整数进行比较。
#include<stdio.h> #define N 100 int main() { int n,i,j,flag=1,a=0; int arr[N]; int arr1[N]; scanf("%d",&n); for(i=0;i<n;i++) //循环n次,输入n个数 { flag=1; //设置一个标志点。当flag=1时说明没有重复,如果有重复flag=0. scanf("%d",&arr[i]); for(j=0;j<i;j++) { if(arr[j]==arr[i]) //输入的与已有数据比较是否重复 { flag=0; //重复时flag=0,且不用继续比较 break; } } if(flag==1) //跳出for循环后flag=1,说明没有重复。没有重复的数据放入一个新的数组中。 { arr1[a]=arr[i]; a++; } } for(i=0;i<a;i++) //打印数组 { printf("%d ",arr1[i]); } return 0; }
下面是第三组:
这一组代码,是在第二组的基础上优化。不再创建新的数组存放。
#include<stdio.h> #define N 100 int main() { int n,i,j; int arr[N]; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&arr[i]); for(j=0;j<i;j++) { if(arr[j]==arr[i]) { i--; //如果有重复,这里的i--,代码再次跳到最外层for循环执行i++;相当于i没 //变,直接覆盖上次输入所重复的值。 break; //找到重复后就可以直接跳出循环 } } } for(i=0;i<a;i++) //打印数组 { printf("%d ",arr1[i]); } return 0; }
下面是第四组:
这组代码相对于前三组,思路不相同。但是运行效率高了很多。而这组代码的关键就是判断数组。也是因判断数组而大大提高了运行效率。
#define n 10 #include<stdio.h> int main() { int i = 1; int num[n]; //储存数组 int judge[n] = { 0 }; //判断重复数组。判断的方法就是:你所要储存输入的数值为该数组下标,一但输入这个数值,以该数值为下标的判断数组的值变成1.以后每输入一个值只需判断以该数值为下标的判断数组中的值是否为1即可。如果不为1,说明没有重复。 scanf("%d", &num[0]); //输入第一个数值 printf("%d", num[0]); //打印第一个数值 judge[num[0]]++; //以该数值为下标的判断数组的值变成1 while (i < n) { scanf("%d", &num[i]); if (judge[num[i]] != 0) //判断以该数值为下标的判断数组中的值是否为1 { printf("%d ", num[i]); //没有重复,打印出该值 judge[num[i]]++; //没有重复后,以该数值为下标的判断数组的值变成1 } i++; } }
三、总结
数组去重对于初学者来说可能会有一点难,但学到后面我们会发现思路并不是很难,一步一步分析,主要是考虑好各种情况和边界问题。