「PAT乙级真题解析」Basic Level 1022D进制的A+B (问题分析+完整步骤+伪代码描述+提交通过代码)

题目给定两个整数, 要求两数求和之后将结果转为指定进制的数. 这里需要我们明确的是"转为指定进制"如何进行?

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

Table of Contents

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

PAT乙级BasicLevelPractice 1022

问题分析

题目给定两个整数, 要求两数求和之后将结果转为指定进制的数. 这里需要我们明确的是"转为指定进制"如何进行?

进制的转换

选择比较常见且简单的二进制和十六进制为例.

二进制

10这个数转为二进制时, 将"10"表示为:
10 = 2^0 * 0 + 2^1 * 0 + 2^2 * 1 + 2^3 * 1 然后将后面的"乘数"从右往左重新排列, 得到"1100", 这就是"10"转为二进制之后的数值。

十六进制

同上, 将"10"表示为: 10 = 16 ^ 0 * 10 = 16 ^ 0 * a (10在16进制中用a表示)

我们只要能够得到上面表达式里的每个"乘数"即可。 或许在二进制中比较难看出来"乘数"的生成规律。 但是十六进制的情况下, 乘数为"10", 与10对16取模的余数一样 (可以往余数方面猜然后验证这件事) - 事实上, 验证想法后发现, 一次取余运算之后, 下一次取余用的数值是原数值除以上一次取余模数的商. 比如二进制中:

  • 10 % 1 = 0;
  • (10 / 1) % 2 = 0;
  • (10 / 1 / 2) % 4 = 1
  • (10 / 1 / 2 / 4) % 8 = 1

所以, 事实上就是10对进制数的各个次方取余, 余数就是"乘数". 我们只要不断取余, 把余数存起来, 明确好终止条件, 就可以得到进制转换后的数

数值溢出

题目给定的是两个数, 然后求和; 而不是直接给定一个数. 这种让我们自己做加法的行为, 要小心题目想让我们数值溢出的心机 而根据题目给定的数值范围, 即便两个数都取最大值, 相加之后也不会超过C语言int的表示范围, 所以不会溢出. 虚惊一场.

完整描述步骤

  1. 获取输入 整数A, B, 指定进制数D
  2. A,B求和得到sum
  3. 如果sum不是0, 则进行以下操作:
    • sum 对 D 取余, 得到余数 R (存储, 最后要用)
    • sum = sum / D
  4. 将得到的需要从右往左输出(数组从末尾往首部输出)

伪代码描述

  1. get input A, B, D
  2. sum = A + B
  3. set a array or list or just a space to store the result
  4. set a counter to count the length of result (if can not call function like result.length)
  5. while sum != 0: remainder = sum % D sum = sum / D put remainder into result counter ++;
  6. for (int i = count - 1; i >= 0; i--) print(result[i])

完整提交代码

/*
# 问题分析
题目给定两个整数, 要求两数求和之后将结果转为指定进制的数.
这里需要我们明确的是"转为指定进制"如何进行?
 
## 进制的转换
选择比较常见且简单的二进制和十六进制为例.
### 二进制
10这个数转为二进制时, 将"10"表示为:\
10 = 2^0 * 0 + 2^1 * 0 + 2^2 * 1 + 2^3 * 1
然后将后面的"乘数"从右往左重新排列, 得到"1100", 这就是"10"转为二进制之后的数值。
### 十六进制
同上, 将"10"表示为:
10 = 16 ^ 0 * 10 = 16 ^ 0 * a (10在16进制中用a表示)
 
我们只要能够得到上面表达式里的每个"乘数"即可。
或许在二进制中比较难看出来"乘数"的生成规律。
但是十六进制的情况下, 乘数为"10", 与10对16取模的余数一样 (可以往余数方面猜然后验证这件事)
    - 事实上, 验证想法后发现, 一次取余运算之后, 下一次取余用的数值是原数值除以上一次取余模数的商. 比如二进制中:
        - 10 % 1 = 0;
        - (10 / 1) % 2 = 0;
        - (10 / 1 / 2) % 4 = 1
        - (10 / 1 / 2 / 4) % 8 = 1
所以, 事实上就是10对进制数的各个次方取余, 余数就是"乘数".
我们只要不断取余, 把余数存起来, 明确好终止条件, 就可以得到进制转换后的数
 
## 数值溢出
题目给定的是两个数, 然后求和; 而不是直接给定一个数. 这种让我们自己做加法的行为, 要小心题目想让我们数值溢出的心机
而根据题目给定的数值范围, 即便两个数都取最大值, 相加之后也不会超过C语言int的表示范围, 所以不会溢出. 虚惊一场.
 
# 完整描述步骤
1. 获取输入 整数A, B, 指定进制数D
2. A,B求和得到sum
3. 如果sum不是0, 则进行以下操作:
    - sum 对 D 取余, 得到余数 R (存储, 最后要用)
    - sum = sum / D
4. 将得到的需要从右往左输出(数组从末尾往首部输出)
 
# 伪代码描述
 
1. get input A, B, D
2. sum = A + B
3. set a array or list or just a space to store the result
4. set a counter to count the length of result (if can not call function like result.length)
5. while sum != 0:
    remainder = sum % D
    sum = sum / D
    put remainder into result
    counter ++;
6. for (int i = count - 1; i >= 0; i--)
    print(result[i])
*/
 
int main(){
    int A, B, D;
    scanf("%d %d %d", &A, &B, &D);
    int result[100] = {0};
    int size = 0;
    int sum = A + B;
 
    if (sum == 0){
        printf("0");
        return 0;
    }
    
    while (sum != 0){
        result[size] = sum % D;
        sum = sum / D;
        size ++;
    }
    
    for (int i = size - 1; i >= 0; i--){
        printf("%d", result[i]);
    }
}
「PAT乙级真题解析」Basic Level 1022D进制的A+B (问题分析+完整步骤+伪代码描述+提交通过代码) | 生活糖果