代码编织梦想

 

题目:

 我的答案:

一、信息

 

二、分析

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.哈希表和红黑树学到了新的用法。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tang7mj/article/details/130912191

【leetcode60天带刷】day02—— 977.有序数组的平方、209.长度最小的子数组、 59.螺旋矩阵ii-爱代码爱编程

题目:997.有序数组的平方 Leetcode原题链接:997.有序数组的平方——力扣  思考历程与知识点:  题目的意思很简单,就是把每个数的平方,按从小到大的顺序排个序,再输出出来。 第一想法是先每个数平方一遍,用sort()函数排序一步到位。但是这道题用sort时间复杂度很高,主要考查的是对双指针的理解,所以两种方法都做一

最小生成树-爱代码爱编程

文章目录 前言一、最小生成树是什么?二、最小生成树算法1、MST性质2、普里姆(Prim)算法2.1 算法思路2.2 算法的时间复杂度 3、克鲁斯卡尔(Kruscal)算法3.1 算法思路3.2 算法的

juc学习(一)-爱代码爱编程

目录 多线程并发与并行顺序执行并发执行并行执行 锁机制重量级锁轻量级锁偏向锁锁消除和锁粗化 JMM内存模型Java内存模型重排序volatile关键字