题目:
我的答案:
一、信息
二、分析
1.如何选择数据结构?
2.如何选择算法有很多思路?
3.如何用文件实现输入输出?
三、思考
疑问1
我选择了一开始数组选择使用数组是一个不错的选择,尤其在这个问题中,因为我们需要统计数字0到9在页码中出现的次数。
使用数组可以方便地记录每个数字的出现次数。我们可以创建一个长度为10的整数数组,索引从0到9,分别表示数字0到9。通过遍历页码并根据每个页码的数字来更新相应数字在数组中的计数。
优点:
- 数组具有固定的大小,可以直接使用索引进行访问,查找和更新操作的时间复杂度是常数级别的,非常高效。
- 在这个问题中,数字0到9的范围是固定的,因此使用数组可以直接映射数字到数组的索引,使得代码实现简单明了。
然而,需要注意的是,如果输入范围超出了数字0到9,或者需要处理更大范围的数字,使用固定大小的数组可能不再适用。在这种情况下,可以考虑其他数据结构,如哈希表(HashMap)或红黑树(Red-Black Tree),以动态地处理更大范围的数字。
怎么解决这个问题呢?
如果书的页数范围在1到10的九次方(1到1,000,000,000)之间,那么使用数组作为数据结构可能会导致内存占用过大,因为需要创建一个长度为10的十亿级别的数组。
在这种情况下,使用固定大小的数组将不再是一个合适的选择。相反,可以考虑使用动态数据结构来处理更大范围的数字。
一种可行的方法是使用哈希表(HashMap)或类似的键值对存储结构。哈希表可以根据键(数字)快速查找和更新对应的值(出现次数)。通过将数字作为键,将其出现次数作为值,可以有效地统计数字在页码中的出现次数。
优点:
- 哈希表可以动态调整大小,根据需要分配内存,因此可以适应大范围的数字。
- 在平均情况下,哈希表的插入、查找和更新操作的时间复杂度是常数级别的,因此仍然具有高效性能。
在使用哈希表时,将每个页码转换为字符串并遍历其每个字符的方法仍然适用。然后,使用哈希表来存储数字的计数,最后将统计结果写入输出文件。
综上所述,对于页数范围在1到10的九次方的问题,使用哈希表作为数据结构是更好的选择。它能够有效地处理大范围的数字,并提供高效的查找和更新操作。
疑问2 如何用算法实现页数的统计呢?
我的想法1是通过把n位数进行拆分个位十位百位...然后统计,遇到同样的字符串我们就可以对变量++,这是遍历的思想
我的想法2是通过寻找背后的数学规律然后找到数学式子然后求解,这比较考验编程者的数学水平。
最终的思路是选择迭代遍历即第一个
疑问3 如何用文件实现文件的输入输出?
要使用文件实现题目中的输入输出功能,可以按照以下步骤进行操作:
1. 输入文件处理:
- 在代码中使用 `fopen` 函数打开输入文件,指定文件名和打开模式(如 `"r"`)。
- 使用 `fscanf` 或 `fgets` 函数从输入文件中读取数据,将其存储到适当的变量中。
- 关闭输入文件,使用 `fclose` 函数关闭文件句柄。
2. 输出文件处理:
- 在代码中使用 `fopen` 函数打开输出文件,指定文件名和打开模式(如 `"w"`)。
- 使用 `fprintf` 函数将要输出的数据写入输出文件。
- 关闭输出文件,使用 `fclose` 函数关闭文件句柄。
下面是一个示例代码,演示了如何使用文件实现输入和输出功能:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
// 读取输入文件
FILE* inputFile = fopen("input.txt", "r");
if (inputFile == NULL) {
printf("无法打开输入文件\n");
return 1;
}
fscanf(inputFile, "%d", &n);
fclose(inputFile);
// 进行数字统计操作
// ...
// 将结果写入输出文件
FILE* outputFile = fopen("output.txt", "w");
if (outputFile == NULL) {
printf("无法打开输出文件\n");
return 1;
}
fprintf(outputFile, "统计结果\n");
// 输出结果
// ...
fclose(outputFile);
return 0;
}
在这个示例中,代码使用了 `fopen` 函数打开输入文件和输出文件。使用 `fscanf` 函数从输入文件中读取一个整数 `n`,并使用 `fprintf` 函数将统计结果写入输出文件。
请注意,使用文件进行输入输出需要确保输入文件和输出文件存在,并且程序对文件的访问权限是允许的。
四、具体实现步骤思路计划
传统的流程图:
开始
│
├─ 打开输入文件
│ ├─ 若文件打开失败,则输出错误信息,结束程序
│ └─ 读取输入数据
│ ├─ 若读取失败,则输出错误信息,结束程序
│ └─ 关闭输入文件
│
├─ 分配数字计数器的内存空间
│ ├─ 若内存分配失败,则输出错误信息,结束程序
│ └─ 初始化数字计数器
│
├─ 数字统计
│ └─ 循环直到 n 为 0
│ ├─ 取 n 的个位数字
│ └─ 将对应的数字计数器加一
│ └─ 更新 n 为 n 的除以 10 的商
│
├─ 打开输出文件
│ ├─ 若文件打开失败,则输出错误信息,释放内存,结束程序
│ └─ 将数字统计结果写入输出文件
│ ├─ 循环遍历数字计数器
│ └─ 将每个数字的计数写入输出文件
│
└─ 关闭输出文件
│
结束
五、代码实现
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int digit;
int count;
} DigitCount;
void countDigits(int n, DigitCount* counts) {
while (n > 0) {
int digit = n % 10;
counts[digit].count++;
n /= 10;
}
}
int main() {
int n;
FILE* inputFile = fopen("input.txt", "r");
if (inputFile == NULL) {
printf("无法打开输入文件\n");
return 1;
}
fscanf(inputFile, "%d", &n);
fclose(inputFile);
DigitCount* counts = (DigitCount*)calloc(10, sizeof(DigitCount));
if (counts == NULL) {
printf("内存分配失败\n");
return 1;
}
countDigits(n, counts);
FILE* outputFile = fopen("output.txt", "w");
if (outputFile == NULL) {
printf("无法打开输出文件\n");
free(counts);
return 1;
}
for (int i = 0; i < 10; i++) {
fprintf(outputFile, "%d\n", counts[i].count);
}
fclose(outputFile);
free(counts);
return 0;
}
六、正确答案
七、反思总结
我有什么不足?
1.C语言文件学的一坨大便得赶紧捡起来
2.哈希表也忘了怎么实现了就知道有这回事还得翻书。
我学到了什么?
1.文件实现输入输出如何实现
2.多种处理这种问题的思路
3.哈希表和红黑树学到了新的用法。