严正声明:该文档仅供作学习参考,禁止直接搬运作作业!!!
一、题目:
实验内容:
编写程序,实现如下任务:从键盘输入若干个整数,输入整数的个数小于
100,其值在-100~100 范围内,用-1 作为输入结束的标志。统计每个整数的个数
并从大到小排序,输出排序后的结果。例如:
提示:定义两个数组,一个用来存放输入整数,另一个用来存放统计信息。
二、分析:
1.思路分析:程序大致完成4个功能:
a.存储输入的数字并计算出现的频率;
b.按输入顺序输出存储的数字及对应频率;
c.按照频率排序;
d.输出排序后的结果;
2.易错点、重难点总结:
(1)问题:数据与其所对应次数的元素在两个数组中怎么联系在一起:
解决:在记录次数的数组中让要保存的那个数字作为本数组中元素的下标,这样就可以让一个数对应一个记录次数数组的一个元素。且由于下标不可为负数,通过num+100将范围[-100, 100]映射到[0, 200];
(2)问题:怎么实现排序:
解决:用冒泡排序,但注意比较的是次数,交换的是数,而数的交换由于一个数对应一个记录次数数组的一个元素而不会影响到次数数组。
(3)问题:数组遍历时会重复输出:
解决:用一个标记数组flag[],没输出前对于flag为0,输出后标记为1,并用if判断是否输出过。注意与次数数组一样,要通过num+100将范围[-100, 100]映射到[0, 200]来处理负数的问题。其次,注意在第二次输出前标记的重置。
(4)其他:输入合法的问题,超过次数的问题,如程序中所示,用if判断加以完成。
三、源码:
#include <stdio.h>
int main() {
int input[100]; // 用于存放输入整数
int count[201] = {0}; // 用于存放统计信息,范围是-100~100,共201个数
int flag[201] = {0}; //记录是否输出过的数组
printf("请输入数字(-100~100),-1作为输入结束,请输入小于100个数:\n");
// 读取输入整数,直到输入-1为止
int num, i = 0;
while (scanf("%d", &num) == 1 && num != -1) {
if (i >= 100) {
printf("输入个数超限!\n");
break;
}
if (num <= -100 || num >= 100) {
printf("输入不合法,请重新输入!\n");
continue;
}
input[i] = num;
i++;
count[num + 100]++; // 统计每个整数的个数,将范围[-100, 100]映射到[0, 200]
}
printf("数字\t频率\n");
// 按输入顺序输出统计信息
for (int j = 0; j < i; j++) {
if (flag[input[j] + 100] == 0) {
printf("%d\t%d\n", input[j], count[input[j] + 100]);
flag[input[j] + 100] = 1;
}
}
// 冒泡排序,按频率从大到小排序
for (int j = 0; j < i - 1; j++) {
for (int k = 0; k < i - j - 1; k++) {
if (count[input[k] + 100] < count[input[k + 1] + 100]) {
int temp = input[k];
input[k] = input[k + 1];
input[k + 1] = temp;
}
}
}
printf("排序后的结果:\n");
printf("数字\t频率\n");
//重置标记
for (int j = 0; j < 201; j++) {
flag[j] = 0;
}
// 输出排序后的结果
for (int j = 0; j < i; j++) {
if (flag[input[j] + 100] == 0) {
printf("%d\t%d\n", input[j], count[input[j] + 100]);
flag[input[j] + 100] = 1;
}
}
return 0;
}