首页 > 其他分享 >牛客网一道题以及对我自己屎山代码的反思

牛客网一道题以及对我自己屎山代码的反思

时间:2023-04-10 23:46:20浏览次数:40  
标签:int max 代码 ++ 牛客 numbers 反思 501 size

做这么个题, 费了大劲, 不是有什么地方不会需要去查, 也不是没思路, 而是纯粹的脑子糊涂。 东一榔头西一棒槌, 把握不住要点,这是做事方式的问题。

这样写代码,绝对是第二天就看不懂的那种

我写的141行屎山
#include <stdio.h>
#include <stdlib.h>

/*
明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再
把这些数从小到大排序,按照排好的顺序输出。数据范围: 1≤n≤1000  ,输入的数字大小满足 1≤val≤500 
*/
//第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。
//输出多行,表示输入数据处理后的结果
int main() 
{
	// 变量size用于储存随机数的个数 
    int size;
    // 读取随机数的个数
	scanf("%d",&size);
	// 测试用,输出读取的随机数的个数
	//printf("%d",size); 
    // 数组numbers用于储存输入的随机数
    int * numbers;
	numbers=(int *) malloc(sizeof(int)*size); 
	// 用于储存中间变量和最值的变量max
	int max=0; 
	// 用于储存重复数字的数量n,其他用途的中间变量m 
	int n=0,m=0; 
 
	// 测试用,输出数组的元素个数
	//printf("%d",sizeof(numbers)/sizeof(numbers[0])); 
	// 为数组读取第一个值,用于开启判断;
	scanf("%d",&numbers[0]);
	// 接收随机数的输入,同时判断是否有重复 ,外循环从1开始,因为前面读取了数组的第一个值 
	for (int i=1;i<size;i++)
	{
		// 临时使用max充当中间变量 
		scanf("%d",&max);
		for (int j=0;j<i;j++)
		{
			// 相等意味着重复了,赋值501 
			if (max==numbers[j])
			{
				numbers[i]=501;
				n++; 
				break;
			}
			// 不相等意味着没重复,读值即可 
			else
			{
				numbers[i]=max;
			} 
		}
		
	} 
	// 测试用,输出数组
	for (int i=0;i<size;i++)
	{
		printf("numbers[%d]=%d\n",i,numbers[i]);
	}
	printf("=============\n");
	// 把所有的501放到数组后边,max做中间变量 
	for (int i=0;i<size-n;i++)
	{
		if (numbers[i]==501)
		{
			// 测试用,输出元素位置 
			printf("numbers[%d]=%d\n", i, numbers[i]);
			// 判断后面有无501,不能把后面的501放前面去 
			while (numbers[size-1-m]==501)
			{
				printf("numbers[%d]=%d等于501\n", size - 1 - m, numbers[size - 1 - m]);
				m++;
			}
			// 储存后边的值到max,把501放过去,把后面的值放过来 
			printf("和numbers[%d]=%d交换\n", size - 1 - m, numbers[size - 1 - m]);
			max=numbers[size-1-m];
			numbers[size-1-m]= numbers[i];
			numbers[i]=max;
			// 测试用,输出 numbers[size-1-m]和 numbers[i]
			printf("交换之后\n");
			printf("numbers[%d]=%d\n",i,numbers[i]);
			printf("numbers[%d]=%d\n",size-1-m,numbers[size-1-m]);
			printf("############\n");
			m++;
		}
	} 
	// 测试用,输出数组
	for (int i=0;i<size;i++)
	{
		printf("numbers[%d]=%d\n",i,numbers[i]);
	}
	printf("=============\n");
	// 改变数组的大小
	size=size-n;
	numbers=(int *) realloc(numbers,sizeof(int)*(size)); 
	// 测试用,输出数组
	for (int i=0;i<size;i++)
	{
		printf("numbers[%d]=%d\n",i,numbers[i]);
	}
	printf("=============\n");
	
	// 排大小,max储存大值,m储存对应该值的序号 ,n储存排好的个数 
	n=0;  
	// size-1次循环即可,最后一位不用比,n计数 
	// 两个数字比一次,三个数字比两次..... 
	for (int i=0;i<size-1;i++)
	{
		// 每次都从numbers[0]开始比
		m=0; 
		max=numbers[m];
		// 每排好一个数,下一次就少比一次,用n计数 从1开始 
		for (int j=0;j<size-n;j++)
		{
			// 比max大则成为max,记序号 
			if (max<numbers[j])
			{
				max=numbers[j];
				m=j;
			} 
		} 
		// 完成一次比较,与末位元素交换位置,n++
		printf("max=%d\n",max);
		printf("没换之前末位数位置numbers[%d]=%d\n",size-1-n,numbers[size-1-n]);
		printf("没换之前最大数位置numbers[%d]=%d\n",m,numbers[m]);
		numbers[m]=numbers[size-1-n];
		printf("换了之后最大数位置numbers[%d]=%d\n",m,numbers[m]);
		numbers[size-1-n]=max;
		printf("换了之后末位数位置numbers[%d]=%d\n",size-1-n,numbers[size-1-n]);
		n++; 
	}
	
	// 测试用,输出数组
	for (int i=0;i<size;i++)
	{
		printf("numbers[%d]=%d\n",i,numbers[i]);
	}
	printf("=============\n");
	
	// 释放内存
	free(numbers); 
	
    return 0;
}
去掉测试输出部分后的87行屎山
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 变量size用于储存随机数的个数
    int size;
    // 读取随机数的个数
    scanf("%d", &size);
    // 数组numbers用于储存输入的随机数
    int* numbers;
    numbers = (int*) malloc(sizeof(int) * size);
    // 用于储存中间变量和最值的变量max
    int max = 0;
    // 用于储存重复数字的数量n,其他用途的中间变量m
    int n = 0, m = 0;

    // 为数组读取第一个值,用于开启判断;
    scanf("%d", &numbers[0]);
    // 接收随机数的输入,同时判断是否有重复 ,外循环从1开始,因为前面读取了数组的第一个值
    for (int i = 1; i < size; i++) {
        // 临时使用max充当中间变量
        scanf("%d", &max);
        for (int j = 0; j < i; j++) {
            // 相等意味着重复了,赋值501
            if (max == numbers[j]) {
                numbers[i] = 501;
                n++;
                break;
            }
            // 不相等意味着没重复,读值即可
            else {
                numbers[i] = max;
            }
        }
    }
    // 把所有的501放到数组后边,max做中间变量
    for (int i = 0; i < size - n; i++) {
        if (numbers[i] == 501) {

            // 判断后面有无501,不能把后面的501放前面去
            while (numbers[size - 1 - m] == 501) {
                m++;
            }
            // 储存后边的值到max,把501放过去,把后面的值放过来
            max = numbers[size - 1 - m];
            numbers[size - 1 - m] = numbers[i];
            numbers[i] = max;
            m++;
        }
    }

    // 改变数组的大小
    size = size - n;
    numbers = (int*) realloc(numbers, sizeof(int) * (size));

    // 排大小,max储存大值,m储存对应该值的序号 ,n储存排好的个数
    n = 0;
    // size-1次循环即可,最后一位不用比,n计数
    // 两个数字比一次,三个数字比两次.....
    for (int i = 0; i < size - 1; i++) {
        // 每次都从numbers[0]开始比
        m = 0;
        max = numbers[m];
        // 每排好一个数,下一次就少比一次,用n计数 从1开始
        for (int j = 0; j < size - n; j++) {
            // 比max大则成为max,记序号
            if (max < numbers[j]) {
                max = numbers[j];
                m = j;
            }
        }
        // 完成一次比较,与末位元素交换位置,n++
        numbers[m] = numbers[size - 1 - n];
        numbers[size - 1 - n] = max;
        n++;
    }

    // 输出数组
    for (int i = 0; i < size; i++) {
        printf("%d\n",numbers[i]);
    }

    // 释放内存
    free(numbers);

    return 0;
}

以上面这道题为例, 我重新捋一遍, 看看到底应该怎么做才是合适的做法


首先,看要求,可以分为接收数据、处理数据、输出数据三部分。
数据的输入是每行一个整数数据,因此可以考虑使用scanf()接收数据;使用一个整型变量存储数字的个数,使用一个整数数组存储所有的数字。
数据的输出是每行一个数据,因此可以使用printf()
数据的处理最麻烦:1、要清除重复数字;2、要知道清除重复数字以后的数字个数;3、要给剩余数字排序。

其次就是看怎么实现(按照今天写的思路来)。
一、数据的输入: 使用一个scanf()接收数字个数size;使用一个for()循环,从0size-1,每一次循环使用一次scanf(),将数字存入numbers[i]
二、数据的输出: 使用一个for()循环,从0size-1,这里的size是更新过大小的,以后用size-n表示,每循环一次使用一次printf()
三、清除重复数字: 需要知道哪些位置是重复的,将这些位置用特殊的整数代替即可。借着输入时的for()循环,当读入第i个数字时,后面接一个从0i-1for(j)循环,把numbers[i]numbers[j]进行比较。如果相同,就把这个读入的数字改为501,也就是numbers[i]=501(题目输入数字的范围是1~500),同时计数器n++,然后退出这个循环,读取下一个数字。这样做,在输入完成时,就已经完成了重复数字的初步处理和统计。。。。。。因为我使用动态数组,可以改变数组的大小,所以我考虑将所有的501排在数组的末尾,方便截断。使用一个0size-n-1for()循环,每次循环判断一次if (numbers[i]==501),如果成立,再使用一个size-10for()循环,每次循环判断一次if (numbers[j]!=501),如果成立,交换numbers[i]numbers[j]的值。因为size_new是不包含重复值的个数,所以外层循环虽然小于内层循环,但一定能把501们放到数组的末尾。。。。。。最后使用realloc()重分配数组的内存,也就是把size变成size-n,截断掉后面的501们。
四、知道清除重复数字以后的数字个数: 这是上一步的副产物,并且在上一步已经使用过了。
五、排序: 选择由大到小排序,也就是最大值放最后,次大值放倒数第二位,以此类推。先做一个for()循环,因为是两两比较,并且不使用循环变量,所以这个for()循环是从0size-n-2。每一次循环,都给max赋初值numbers[0],然后再写一个for()循环,从size-n-10,每次循环都判断一次if (max < numbers[j]),如果成立则把numbers[j]保存在max中,并保存numbers[j]所在的位置jm中,也就是m=j;。当内循环进行到j==0时,交换m位置的值和size-n-1-i位置的值。

我按照文字算法写了代码,略加修改就已经可以使用了,而且占用内存更小,运行更快。最重要的是,我不会急于写一坨谢特,然后再一点一点修改,从而浪费大量时间。我了解到有经验的程序员使用程序框图来实现,我现在不会这些,暂时用文字代替,尽快学会使用程序框图。

不要把时间浪费在会的地方上,会却花费大量时间,不应该。

73行新程序
#include <stdio.h>
#include <stdlib.h>
// 
int main() {
    // 变量size用于储存随机数的个数
    int size;
    // 读取随机数的个数
    scanf("%d", &size);
    // 数组numbers用于储存输入的随机数
    int* numbers;
    numbers = (int*) malloc(sizeof(int) * size);
    // 用于储存中间变量和最值的变量max
    int max = 0;
    // 用于储存重复数字的数量n
    int n = 0, m = 0;

    // 接收随机数的输入,同时判断是否有重复 ,外循环从1开始,因为前面读取了数组的第一个值
    for (int i = 0; i < size; i++) {
        // 临时使用max充当中间变量
        scanf("%d", &numbers[i]);
        for (int j = 0; j < i; j++) {
            // 相等意味着重复了,赋值501
            if (numbers[i] == numbers[j]) {
                numbers[i] = 501;
                n++;
                break;
            }
        }
    }
    // 
    for (int i = 0; i < size - n ; i++) {
        if (numbers[i] == 501) {
            for (int j = size - 1; j > 0; j--) {
                if (numbers[j] != 501) {
                    max = numbers[j];
                    numbers[j] = numbers[i];
                    numbers[i] = max;
                }
            }
        }
    }
    // 
    size = size - n;
    numbers = (int*) realloc(numbers, sizeof(int) * (size));
    // 
    // 
    for (int i = 0; i < size - 1; i++) {
        // 
        m=0;
        max = numbers[0];
        // 
        for (int j = size - 1-i ; j >= 0; j--) {
            // 
            if (max < numbers[j]) {
                max = numbers[j];
                m = j;
            }
            if (j == 0) {
                numbers[m] = numbers[size - 1 - i];
                numbers[size - 1 - i] = max;
            }
        }
    }
    // 输出数组
    for (int i = 0; i < size; i++) {
        printf("%d\n", numbers[i]);
    }

    // 释放内存
    free(numbers);

    return 0;
}

标签:int,max,代码,++,牛客,numbers,反思,501,size
From: https://www.cnblogs.com/Hubugui/p/17304749.html

相关文章

  • 代码重构 V.S 架构重构
    1代码重构定义对软件代码做任何改动以增加可读性或者简化结构而不影响输出结果。目的增加可读性、增加可维护性、可扩展性3关键点不影响输出不修正错误不增加新的功能性代码重构时,发现有个功能实现逻辑不合理,可直接修改吗?当然不可!2架构重构定义通过整系统结构(4R)来修复系统质量......
  • 2023年牛客基础训练营2-I
    题目链接:https://ac.nowcoder.com/acm/contest/46810/I乱搞题,但是有一些差分思想在里面。先将所有的$$x_i都设置为第一个等级。注意到一个性质,不是所有的h都可以使答案发生变化。然后我们可以先求出所有可以使\(x_i\)发生变化的h的最小值,接着从小到大枚举所有h。所有\(x_i都会......
  • gitlab——项目代码迁移
    gitlab——项目代码迁移目的:将原来服务器上的项目代码迁移到另一台服务器上。step1.首先新建一个空文件,将原服务器代码取下来:gitclonehttp://***(原服务器代码地址)step2.进入到取下来的git项目文件夹中:cd*****(取下来的项目文件夹路径)注:step1和step2相当于拉取线......
  • 课上测试-实现分页显示和模糊查询(代码部分)
    今天的软工课上,老师给我们布置了课堂小测试,要求我们做一个简单的科技政策查询系统,具体要能实现模糊查询和分页显示。这里展示我实现的代码。目前实现了基本功能,还有点小不完善,之后再改一改吧。Query.javapackagemain;importdao.Bean;importdatas.DB;importj......
  • mybatispuls的代码生成
    pom文件配置 <!--https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5......
  • R语言MCMC的lme4二元对数Logistic逻辑回归混合效应模型分析吸烟、喝酒和赌博影响数据|
    原文下载链接:http://tecdat.cn/?p=29196最近我们被客户要求撰写关于逻辑回归混合效应模型的研究报告,包括一些图形和统计输出。吸烟、喝酒和赌博被认为是由许多因素造成的。Logistic回归分析是一个非常有效的模型,可以检验各种解释变量和二元反应变量之间的关系。同时,双变量模型分......
  • 没有在线调试功能时,调试代码心得
    1、串口输出数据2、极端情况,没有额外串口时,可以把一个串口先当调试口用,先调试其他功能3、可以控制printf是否可以输出信息4、生成可执行文件时,生成一版带printf输出,一版不带printf输出,调试时两者交替用5、串口发送数据是否正常,接收处理数据是否正常6、串口通信必须保证一端功......
  • Stata中的治疗效果:RA:回归调整、 IPW:逆概率加权、 IPWRA、 AIPW|附代码数据
    全文链接:http://tecdat.cn/?p=10148最近我们被客户要求撰写关于Stata中的治疗效果的研究报告,包括一些图形和统计输出。今天的主题是Stata中的治疗效果。治疗效果估算器根据观察数据估算治疗对结果的因果关系。我们将讨论四种治疗效果估计量:RA:回归调整IPW:逆概率加权I......
  • MATLAB代码:综合能源系统优化模型概述及其鲁棒优化
    MATLAB代码:综合能源系统优化模型概述及其鲁棒优化主要内容:本文在分析典型冷热电联供(combinedcooling,heatandpower,CCHP)系统的基础上,并结合其他优秀lunwen加以补充模型中的不足处,并围绕该系统结构设计了微网调度优化模型构架.在该结构中,选取电气、烟气、蒸汽、......
  • mybatis代码
    /*//根据id查询详情publicvoidselectById()throwsIOException{//接受参数intid=1;//现在是固定数据,以后会变成动态数据//1.获取SqlSessionFactoryStringresource="mybatis-config.xml";InputStreaminputStream=Resourc......