多种思路删除数组中的指定元素

目录

每日一题:序列中删除指定数字                                                        ————来自牛客网BC124

 一、首先咱们看看题目及示例

二、方法思路

(1)暴力覆盖法

(2)“另寻出路“”法

(3)不删而减法

三、总结


每日一题:序列中删除指定数字
                                                        ————来自牛客网BC124

大家好,我是小白,每日登山,顶峰相见
    今天我来给大家讲解一道牛客网上的题,做了这么多题,感觉得和大家分享分享我的解题思路,若有错误,望大家斧正。


 一、首先咱们看看题目及示例

 这道题大致的意思就是让我们删除数组中一个指定的数字,并且不改变相对的顺序。

二、方法思路

(1)暴力覆盖法
 

顾名思义,暴力覆盖法就是用最朴实的方法,也是大家最常想到的方法,用被删除数字的后面那个数字来覆盖他。我们的思路就是首先找到那个数字,也就是需要一个循坏来遍历这个数组,然后让后面的那个数字来覆盖删除数字以达到删除效果,并且不改变数字的顺序。下面看代码

int main() {
    int length = 0, arr[50] = { 0 }, target = 0,many=0;//先将要使用的数组和数组有用的长度以及要删除的目标数列出
    scanf("%d", &length);    //确定长度                 //many为删除元素的个数
    for (int i = 0; i < length; i++) {
        scanf("%d", &arr[i]);  //通过循环的方式将数据输入进数组
    }
    scanf("%d", &target);   //确定删除的数据
    many=deletemany(length, &arr, target);
    int *arr2 = delete(length, &arr, target);//删除后序列,用arr2来接收,此时arr2未定义长度,用名字来代表第一个位置的地址
    for (int i = 0; i < length - many; i++) // 然后接收
        printf("%d ", arr2[i]);
    return 0;
}

首先按照题目要求,输入数组的长度length,一个数组,以及我们想要删除的目标数字target。在数组中存入数据我们,使用最基本的for循环来进行输入,此时之前的length长度就可以用来控制循环的结束。然后我一般的解题习惯是写一个函数(我认为这是一个好习惯,可以重复用,并且使主函数简洁),这里我们先假设写好了一个能够满足这个程序的函数delete,然后数组删除完毕,接下里进行打印函数,因为函数经过删减,我们不知道数组中存在的数的个数,也就不知道打印结束的条件,此时我们另令一个函数deletemany,记录要删减的数字的个数。

两个函数如下

int* delete(int length, int* arr, int target) {
    for (int i = 0; i < length; i++) {   //开始遍历
        while (arr[i] == target&&i!=length-1) {   //当第i+1个元素为要删减的数目时,用while的目的是,让连续的重复数都可以删除
            for (int j = i; j < length-1; j++) {//而当用if时,再次进入循环的时候,此时arr[i]是删除数的下一位的数据
                arr[j] = arr[j + 1];             //再次进入循环后,判断的就是原先i的后两位了,中间连续的就无法判断
            }
            length--;
        }
    }
    return arr;//返回素组最好用地址,我此时取他地址返回,就能接收了
}
int deletemany(int length, int* arr, int target) {
    int j = 0;
    for (int i = 0; i < length; i++) {
        if (arr[i] == target)  j++;       //每找到相同的数字,就用j来记录一次
    }
    return j;
}

deletemany函数容易理解。

   我们来对delete函数,进行分析,首先要将数组的值传出去,我能想到的办法就是将地址传出去,然后用另一个数组来接收,也就是上面的arr2,所以函数的返回值类型是地址,然后数组中是数字,所以是整型。接下来这个方法的难点来了,每次删除数据时用后面一个数据来替代,那么当删除的数据是最后一个的时候呢?此时后面没有数据了,强行覆盖就会超过数据的长度,编码错误。我想的办法就是不管他,让他留在那里,当我检测他是最后一个的时候,我直接不进入循环,但是我deletemany函数已然会记录那个数字,最后打印的时候就不会打印出来。length--也很重要,这个可以记录删减后最后一个元素所在的位置。

(2)“另寻出路“”法

删减一个函数容易出错,那我们就重新找一个数组吧,不删减,在新的数组数组上记录下需要的数组就好了。我的思路是,创建一个新的空数组,要删减的数字就不加入,其余的的数字就加入。下面

int* delete(int length, int* arr, int target) {
   int new[50];
    return &new;
}

看代码

int* delete(int length, int* arr, int target) {
    int new[50],j=0;
    for (int i = 0; i < length; i++) {             //遍历数组依然是必须的
        if(arr[i]!=target) {
            new[j] = arr[i];  
            j++; 
       }
    }              
    return &new;
}

这个函数相对而言就简单很多啦

(3)不删而减法

第三种方法是我们不删除,但是我们将要删的数字记录下来,然后打印的时候不打印这个数字,这个方法更简单,但是却不是一个最佳方法,属于偷懒的方法,下面看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main() {
    int arr[50] = { 0 };
    int length;
    scanf("%d", &length);//行数
    for (int i = 0; i < length; i++) {
        scanf("%d", &arr[i]);//输入序列
    }
    int target; //要删的数字
    scanf("%d", &target);
    for (int i = 0; i < length; i++) {
        if (arr[i] != target)
            printf("%d ", arr[i]); //打印非0的数字
    }
    return 0;
}

三、总结

1、一个题的思维不应该拘泥于一种类型,我们应该打开思维,或许一种比一种简单

2、但是在寻找简单的方法途中,不能偷懒,去找程序要求的bug,而忽略了其本身给我们带来的思维锻炼

3、多亲自动手尝试,会发现很多你不曾注意的细节

4、不会写的时候一定要先思考,然后看看别人的代码,会给你带来很多的思考,集思广益,站在巨人的肩膀上才能成功

最后,蟹蟹大家的观看呀,走过路过,点个赞再走啦,小白的登山之路需要大家的鼓励才能攀高峰!

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

成电吴彦祖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值