「PAT乙级真题解析」Basic Level 1002 (问题分析+完整步骤+伪代码描述+提交通过代码)

[PAT练级笔记] 02 Basic Level 1002

#算法#数据结构#需求分析#pat考试#c语言

Table of Contents

乙级的题目训练主要用来熟悉编程语言的语法和形成良好的编码习惯和编码规范。从小白开始逐步掌握用编程解决问题。

PAT乙级BasicLevelPractice 1002

问题分析

方案一: 模拟 题目直接给定了步骤, 用模拟法将给定步骤写成代码逻辑是最直觉的方案。

我们要考虑的实现点如下:

  1. "计算其各位数字之和":
    • 读入的是一个正整数, 如何获取到各个位置的数字
  2. "汉语拼音写出和的每一位数字":
    • 同上, 和是一个正整数, 如果获取到各个位置的数字
    • 如何将数字转换成对应的汉语拼音

获取正整数的各个数位上的数字:

  • 如果这个正整数类型是一个字符串的话, 那么数字的各个数位就对应上了字符串的每个字符位置, 则获取各个数字就是遍历一趟字符串。所以,我们只要能够把数字的类型变成字符串就可以使用上述方案。
  • 我们考虑"是否可以对一个整数进行遍历", 由于数值没有像字符串一样的"位置索引"概念, 所以直觉上难以"遍历"。
    • 但如果我们把"数位"看作是数字在整个数值中所占位置, 进而考虑我们以往数学知识中有哪些操作是涉及到这个"位置"变化的。
    • 我们可能想到"进位", 而且是逢十进一, 那么我们是否可以利用"进位"获取到各个数位上的数字?
      • 可能的方案是:
        • 进行"退位"操作, 我们是可以很简单地获取到整数的最后一位数字的(使用模运算, 我们在判断奇偶性的时候也使用了模运算),
        • 那么我们就可以先获取当前整数的最后一位, 然后将"十位到最高位"的部分看作是一个新的整数, 继续获取它的最后一位(于是我们获取到了原整数的十位)
        • 如此往复就可以得到每一个数字。

新的问题是: 如何实现「将"十位到最高位"的部分看作是一个新的整数」, 其实我们将这句话换一种描述就可以直觉地想到方法。 我们将问题转述为: 如何去掉一个数的个位数, 使得原本的十位变成个位, 百位变成十位, .... 答案是: 将这个数除以10。于是我们有了第二个获取各个数字的方案:

  • 记录当前整数的最后一位, 然后将其除以10作为新的整数, 然后继续"记录"和"除以10"的操作.
    • 什么时候停止"记录"和"除以10"呢?
      • 当整数为0的时候.

将数字变换成对应的汉语拼音

  • 由于数字只有0-9十种情况, 对应的汉语拼音也是固定的,所以最简单的办法是写十个条件语句, 如果是指定的数字, 就输出对应的汉语拼音
  • 进一步,我们考虑如何优化这十个条件语句, 不然以后出现情况达成百上千的题目, 我们只会狂写条件语句的话就束手无策了
  • 重新描述一下我们的需求/问题: 我们需要一个工具, 可以将我们给定的一个数字, 转换成对应的汉语拼音, 而哪个数字对应哪个拼音我们可以事先规定。
  • 在使用条件语句解决这个问题的时候, 我们的"工具"就是条件语句(10个条件判断)

完整提交代码

 
/*
方案一: 模拟
题目直接给定了步骤, 用模拟法将给定步骤写成代码逻辑是最直觉的方案。
我们要考虑的实现点如下:
1. "计算其各位数字之和":
    - 读入的是一个正整数, 如何获取到各个位置的数字
2. "汉语拼音写出和的每一位数字":
    - 同上, 和是一个正整数, 如果获取到各个位置的数字
    - 如何将数字转换成对应的汉语拼音
- 解决方案:
    1. 获取正整数的各个数位上的数字:
        - 如果这个正整数类型是一个字符串的话, 那么数字的各个数位就对应上了字符串的每个字符位置, 
            则获取各个数字就是遍历一趟字符串。所以,我们只要能够把数字的类型变成字符串就可以使用上述方案。
        - 我们考虑"是否可以对一个整数进行遍历", 由于数值没有像字符串一样的"位置索引"概念, 所以直觉上难以"遍历"。
            但如果我们把"数位"看作是数字在整个数值中所占位置, 进而考虑我们以往数学知识中有哪些操作是涉及到这个"位置"变化的。
            我们可能想到"进位", 而且是逢十进一, 那么我们是否可以利用"进位"获取到各个数位上的数字?
            可能的方案是: 进行"退位"操作, 我们是可以很简单地获取到整数的最后一位数字的(使用模运算, 我们在判断奇偶性的时候也使用了模运算),
                        那么我们就可以先获取当前整数的最后一位, 然后将"十位到最高位"的部分看作是一个新的整数, 继续获取它的最后一位(于是我们获取到了原整数的十位)
                        如此往复就可以得到每一个数字。
                        新的问题是: 如何实现「将"十位到最高位"的部分看作是一个新的整数」, 其实我们将这句话换一种描述就可以直觉地想到方法。
                        我们将问题转述为: 如何去掉一个数的个位数, 使得原本的十位变成个位, 百位变成十位, ....
                            答案是: 将这个数除以10
            于是我们有了第二个获取各个数字的方案: 
                记录当前整数的最后一位, 然后将其除以10作为新的整数, 然后继续"记录"和"除以10"的操作.
                什么时候停止"记录"和"除以10"呢?当整数为0的时候.
    2. 将数字变换成对应的汉语拼音
        - 由于数字只有0-9十种情况, 对应的汉语拼音也是固定的,所以最简单的办法是写十个条件语句, 如果是指定的数字, 就输出对应的汉语拼音
        - 进一步,我们考虑如何优化这十个条件语句, 不然以后出现情况达成百上千的题目, 我们只会狂写条件语句的话就束手无策了
            - 重新描述一下我们的需求/问题: 我们需要一个工具, 可以将我们给定的一个数字, 转换成对应的汉语拼音, 而哪个数字对应哪个拼音我们可以事先规定。
            - 在使用条件语句解决这个问题的时候, 我们的"工具"就是条件语句(10个条件判断)
*/
 
 
# include<stdio.h>
# include<stdlib.h>
 
int char_to_int(char input){
    return ((int)input) - ((int)'0');
}
 
char *write_the_given_number_in_chinese_alphabet(char* number){
    
    char* number_to_chinese_alpbet[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    int sum = 0;
    for (int i = 0; number[i]; i++){
        sum = sum + char_to_int(number[i]);
    }
    char sum_str[4];
    snprintf(sum_str, sizeof(sum_str), "%d", sum);
    
    
    for (int i = 0; sum_str[i]; i++){
        if (i != 0){
            printf(" ");
        }
        int value = char_to_int(sum_str[i]);
        printf("%s", number_to_chinese_alpbet[value]);
    }
 
//     printf("%s", sum_str);
    return "Hello World";
}
 
 
int main(){
    
    char digits[110];
 
    if (scanf("%s", digits) != 1) {
        printf("Failed To Read Integer.\n");
        return 1;
    }
    char* answer;
    answer= write_the_given_number_in_chinese_alphabet(digits);   
}