一、原理
这段代码的主要功能是将不同进制(2 - 16 进制)的数转换为十进制数。其核心原理基于进制转换的基本规则:对于一个 进制数 ,将其按位展开,每一位的数值乘以 的相应次幂(幂次从右到左依次递增),然后将所有结果相加,就可以得到对应的十进制数。
二、步骤
- 字符转换函数
charToValue
:- 该函数接收一个字符
c
作为参数,用于将字符形式的数字转换为对应的数值。 - 如果字符
c
是0
到9
之间的数字字符,通过c - '0'
得到其对应的数值。 - 如果字符
c
是A
到F
之间的大写字母,代表十六进制中的10
到15
,通过10 + (c - 'A')
得到其对应的数值。 - 若输入的字符不符合上述规则,返回
0
(在正常输入情况下,不会执行到这一步)。
- 该函数接收一个字符
- 进制转换函数
change
:- 该函数接收两个参数:一个整数
K
表示输入数字的进制,一个字符串X
表示要转换的 进制数。 - 初始化两个变量:
result
用于存储最终的十进制结果,初始值为0
;base
用于存储当前位的权值,初始值为1
(即 )。 - 从字符串
X
的最后一位(最低位)开始,逐位向前遍历。 - 对于每一位,调用
charToValue
函数将字符转换为对应的数值digit
。 - 将
digit
乘以当前位的权值base
,并累加到result
中。 - 更新
base
为下一位的权值,即base *= K
。 - 遍历结束后,返回
result
,即转换后的十进制数。
- 该函数接收两个参数:一个整数
- 主函数
main
:- 首先读取一个整数
N
,表示要进行转换的数字个数。 - 使用
for
循环进行N
次转换操作。 - 在每次循环中,读取一个整数
K
和一个字符串X
,分别表示当前数字的进制和该进制下的数字。 - 调用
change
函数将X
从 进制转换为十进制,并将结果输出。
- 首先读取一个整数
三、图示法表示步骤(以将十六进制数 2A
转换为十进制为例,即 ,)
步骤 | 操作 | 详细说明 |
---|---|---|
1 | 初始化 | result = 0 ,base = 1 |
2 | 处理最低位 A | |
获取字符 A 对应的数值:调用 charToValue('A') ,得到 10 。 | ||
计算当前位的值:10 * 1 = 10 。 | ||
更新 result :result = 0 + 10 = 10 。 | ||
更新 base :base = 1 * 16 = 16 。 | ||
3 | 处理最高位 2 | |
获取字符 2 对应的数值:调用 charToValue('2') ,得到 2 。 | ||
计算当前位的值:2 * 16 = 32 。 | ||
更新 result :result = 10 + 32 = 42 。 | ||
更新 base :base = 16 * 16 = 256 (此步骤在遍历结束后不再使用)。 | ||
4 | 返回结果 | 最终 result 为 42 ,即十六进制数 2A 转换为十进制后的结果。 |
四、代码关键行注释
#include <iostream>
#include <string>
using namespace std;
// 将字符转换为对应的数值
int charToValue(char c) {
if (c >= '0' && c <= '9') {
return c - '0'; // 数字字符转换为数值
} else if (c >= 'A' && c <= 'F') { // 确保只处理到十六进制
return 10 + (c - 'A'); // 十六进制字母字符转换为数值
}
return 0; // 理论上不会执行到这里
}
// 将 K 进制字符串 X 转换为十进制数
long long change(int K, const string& X) {
long long result = 0; // 存储最终的十进制结果
long long base = 1; // 当前位的权值,初始为 K^0 = 1
// 从右往左遍历每一位(最低位到最高位)
for (int i = X.size() - 1; i >= 0; --i) {
int digit = charToValue(X[i]); // 获取当前位的数值
result += digit * base; // 累加当前位的值到结果中
base *= K; // 更新权值为下一位的 K^(n+1)
}
return result;
}
int main() {
int N;
cin >> N; // 读取要转换的数字个数
for (int i = 0; i < N; ++i) {
int K;
string X;
cin >> K >> X; // 读取当前数字的进制 K 和该进制下的数字 X
cout << change(K, X) << endl; // 调用 change 函数进行转换并输出结果
}
return 0;
}
五、完整代码程序
完整代码就是上述所展示的代码,再次列出如下:
#include <iostream>
#include <string>
using namespace std;
int charToValue(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'A' && c <= 'F') {
return 10 + (c - 'A');
}
return 0;
}
long long change(int K, const string& X) {
long long result = 0;
long long base = 1;
for (int i = X.size() - 1; i >= 0; --i) {
int digit = charToValue(X[i]);
result += digit * base;
base *= K;
}
return result;
}
int main() {
int N;
cin >> N;
for (int i = 0; i < N; ++i) {
int K;
string X;
cin >> K >> X;
cout << change(K, X) << endl;
}
return 0;
}
六、时间复杂度
charToValue
函数:该函数只进行简单的字符判断和算术运算,时间复杂度为 ,因为无论输入的字符是什么,执行的操作次数都是固定的。change
函数:函数中有一个for
循环遍历字符串X
的每一位,循环执行的次数取决于字符串X
的长度,设字符串X
的长度为 ,则时间复杂度为 。main
函数:主函数中有一个for
循环执行N
次,每次循环中调用change
函数,假设每次输入的字符串长度平均为 ,则总的时间复杂度为 。
七、总结
这段代码通过合理的函数封装,实现了将不同进制(2 - 16 进制)的数转换为十进制数的功能。代码逻辑清晰,charToValue
函数负责字符到数值的转换,change
函数利用按位展开的原理完成进制转换,主函数则控制多次转换操作的输入和输出。不过,代码存在一些可以改进的地方:
- 输入验证方面:代码没有对输入的进制
K
和字符串X
进行有效性检查。例如,当输入的进制K
不在 2 到 16 的范围内,或者字符串X
中包含不符合该进制的字符时,程序可能会出现错误的结果。可以添加相应的输入验证逻辑,提高代码的健壮性。 - 功能拓展方面:代码仅实现了从其他进制到十进制的转换,如果需要实现十进制到其他进制的转换,或者更广泛的