做这么个题, 费了大劲, 不是有什么地方不会需要去查, 也不是没思路, 而是纯粹的脑子糊涂。 东一榔头西一棒槌, 把握不住要点,这是做事方式的问题。
这样写代码,绝对是第二天就看不懂的那种
我写的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()
循环,从0
到size-1
,每一次循环使用一次scanf()
,将数字存入numbers[i]
二、数据的输出: 使用一个for()
循环,从0
到size-1
,这里的size
是更新过大小的,以后用size-n
表示,每循环一次使用一次printf()
三、清除重复数字: 需要知道哪些位置是重复的,将这些位置用特殊的整数代替即可。借着输入时的for()
循环,当读入第i
个数字时,后面接一个从0
到i-1
的for(j)
循环,把numbers[i]
与numbers[j]
进行比较。如果相同,就把这个读入的数字改为501,也就是numbers[i]=501
(题目输入数字的范围是1~500),同时计数器n++
,然后退出这个循环,读取下一个数字。这样做,在输入完成时,就已经完成了重复数字的初步处理和统计。。。。。。因为我使用动态数组,可以改变数组的大小,所以我考虑将所有的501
排在数组的末尾,方便截断。使用一个0
到size-n-1
的for()
循环,每次循环判断一次if (numbers[i]==501)
,如果成立,再使用一个size-1
到0
的for()
循环,每次循环判断一次if (numbers[j]!=501)
,如果成立,交换numbers[i]
和numbers[j]
的值。因为size_new
是不包含重复值的个数,所以外层循环虽然小于内层循环,但一定能把501
们放到数组的末尾。。。。。。最后使用realloc()
重分配数组的内存,也就是把size
变成size-n
,截断掉后面的501们。
四、知道清除重复数字以后的数字个数: 这是上一步的副产物,并且在上一步已经使用过了。
五、排序: 选择由大到小排序,也就是最大值放最后,次大值放倒数第二位,以此类推。先做一个for()
循环,因为是两两比较,并且不使用循环变量,所以这个for()
循环是从0
到size-n-2
。每一次循环,都给max
赋初值numbers[0]
,然后再写一个for()
循环,从size-n-1
到0
,每次循环都判断一次if (max < numbers[j])
,如果成立则把numbers[j]
保存在max
中,并保存numbers[j]
所在的位置j
到m
中,也就是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;
}