删除数组中重复出现的值

简介: 删除数组中重复出现的值

一、题目描述


我们先来具体描述一下题目所表达的意思:你首先在键盘上输入一个数字,这个数字就是你要输入数字的个数。然后输入一组数据,把这组数据保留在一个数组当中。最后查重,删除掉多次出现多余的数值,最终输出的结果是所有重复的数字只保留第一次出现的那份。


c4c120475f744007bba0e718cda1f335.png


二、思路讲解


 一共写出来四组代码,经过不断的思考,代码是越来越简单。但是前三组的代码思路基本上是相同的,只不过是代码优化了。第四组是另一种思路,也是运行效率最高的一种。

下面是第一组:

这种代码是先把整个数据输入其中。然后再一一查询。


#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++;
    }
}


三、总结


 数组去重对于初学者来说可能会有一点难,但学到后面我们会发现思路并不是很难,一步一步分析,主要是考虑好各种情况和边界问题。


相关文章
|
4月前
|
JavaScript 前端开发 索引
如何判断一个值是否在数组内?
如何判断一个值是否在数组内?
|
2月前
|
语音技术
语音识别-----列表的常用操作课后练习讲解,用变量追加,取出第一个,取出最后一个,下标位置,列表的循环遍历,下标+1的写法,len下标可以小于这个值,while循环对index循环的遍历
语音识别-----列表的常用操作课后练习讲解,用变量追加,取出第一个,取出最后一个,下标位置,列表的循环遍历,下标+1的写法,len下标可以小于这个值,while循环对index循环的遍历
数组筛选,将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10元素选出来,放入新数组,声明一个新的数组用于存放新数据newArr,遍历原来的旧数组,找到大于10的元素,依次追加新数组
数组筛选,将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10元素选出来,放入新数组,声明一个新的数组用于存放新数据newArr,遍历原来的旧数组,找到大于10的元素,依次追加新数组
|
3月前
|
索引
删除数组中的指定元素(了解如何删除数组中的指定元素,并返回一个新的数组,看这一篇就足够了!)
删除数组中的指定元素(了解如何删除数组中的指定元素,并返回一个新的数组,看这一篇就足够了!)
更改元素的值
代码示例修改了首个 `&lt;title&gt;` 元素的文本节点值,将它变为 &quot;Easy Cooking&quot;。步骤包括加载 &quot;books.xml&quot; 到 xmlDoc,获取第一个 `&lt;title&gt;` 的子节点,然后设置其nodeValue。
|
4月前
|
算法 测试技术 C#
【哈希映射】【 哈希集合】 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
【哈希映射】【 哈希集合】 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
|
4月前
判断两个不重复的list集合是否相等 只比较元素值 不比较顺序
判断两个不重复的list集合是否相等 只比较元素值 不比较顺序
54 0
|
10月前
442. 数组中重复的数据
442. 数组中重复的数据
|
11月前
|
存储 JavaScript 前端开发
过滤掉数组中重复的元素
过滤掉数组中重复的元素
43 0