数组重复数字删除

如果有一个数组,无论是随机生成的还是自己输入的,对数组中重复出现的数字,想要做到删除的效果,如何利用C语言实现?

例如我给出一个数组:

int arr[10]={ 1,2,3,2,4,2,5,4,4,2};

可以看到数组中除了1其他数字都是重复出现的,那我最后只想留下这样的数组:

int arr[5]={1,2,3,4,5,};

我该如何实现呢?请先忽略这里数组的顺序,关于数组排序的实现方法会在下一篇文章中给出。可以看到,这里我将重复出现的数字都进行了删除,并且数组定义的常量也从10变成了5。

我们不妨做这样一个设想,如果我要删除数组中重复出现的数字,我必须要进行每一个数字的比对就需要从数组的第一个数字arr[0],依次和数组后面每一个数字进行比较,如果数字一样,我就将一样的数字删除。那这是第一次遍历,第一次遍历结束,我还需要对数组中第二个数字、第三个数字...第N个数字依次比较。这里就需要利用循环来实现。理解了代码思想之后,我先给出整体代码:

#include<stdio.h>

int main()
{
  //完成数组的初始化
  int arr[10]={1,2,3,2,4,2,5,4,4,2};
  //将数组初始化的常量赋值给N
  int N=10;
  int i=0;
  //第一次循环,从数组的第一个元素到最后一个元素
  for(i=0;i<N;i++)
  {
    int j=0;
    //第二次循环,这是从以i为下标的后面一个元素直到最后一个元素
    for(j=i+1;j<N;j++) 
    {  
      //引入判断,如果以i为下标的元素等于以j为下标的元素
      if(arr[i]==arr[j])
      {
        int k=0;
        //第三次循环,从以j为下标的元素开始到最后一个元素
        for(k=j;k<N;k++)
        {
          //将从以k为下标之后的所有元素向前移一位
          arr[k]=arr[k+1];
        }
        //因为最后一位被随机值覆盖,所以数组少了一位
        N=N-1;
        //这一步我接下来会给出解释!!!(究极重点!!)
        j=j-1;
      }
    }
  }
  //循环输出数组
  for(i=0;i<N;i++)
  {
    printf("%d ",arr[i]);
  }
  return 0;
}

代码中利用了三次循环,我们就需要理解每一次循环的含义。第一次循环:就是从arr[0]到arr[N]中的所有数字,我依次取出来一遍。第二次循环:我要取出来第一次循环取出的数字之后的每一个数字。那么有人就会问了,为什么要是第一次循环取出的数字之后的数字,也就是arr[i]之后的数组元素。对于一个数组,第一项元素和之后每一个元素做比较完成,我后面的元素还需要返回去和第一项比吗?显然是不用的。就拿我们代码中的数组来举例子,i=0时,arr[0]=1,我依次和后面的元素比较完成,I=1时,arr[1]=2,我显然是要和arr[1]之后的元素比较,而不需要再比较arr[0];这就是第二次循环的意义。第三次循环:第三次循环之前是有if判断语句在的,就是我在一二次循环中发现了相同的元素,我利用第三次循环将相同元素之后的所有元素向前移一项,覆盖掉从相同元素开始到数组结束的所有元素。我们举例的代码,数组中10个整型,arr[9]=arr[10],那第10位元素用谁覆盖呢?这里就不需要深究了,因为我们数组初始化中,只给了10个数字,所以最后一位被随机值覆盖了。

了解三次循环各自的用途之后,还有一个需要注意的地方。那就是我们if判断语句中最后一行代码:j=j-1,这个代码的作用是什么?拿我们举例子的数组:

int arr[10]={ 1,2,3,2,4,2,5,4,4,2};

如果没有j=j-1;最后代码运行结果就会是:

int arr[10]={ 1,2,3,4,5,4};

这是为什么?因为我们arr[7],arr[8]都是4,当我们发现第一个4和之前某一位的元素重复时,我利用后一位向前移覆盖掉了第一个4,那我第二个4就到第一4的位置上了,我继续循环 j++了,从后一位开始扫描了,就忽略我向前移的这一个4。所以我们要有j=j-1,遇见相同元素,在j=j-1和循环调整结构中的 j++ 相互作用下保持j不变。这样可以保证我们不漏掉每一个重复元素。

这就是利用多次循环来删除数组中重复出现的数字的代码实现。

能力有限,多多包涵。

  • 17
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石Ww.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值