P1143 进制转换
问题概述
题目要求我们实现一个程序,将一个n进制的数转换为m进制的数。其中n和m的范围都是2到16,当进制大于10时,使用大写字母A-F表示10-15的数字。
解题思路
解决这个问题可以分为两个主要步骤:
-
将n进制数转换为十进制数:这是进制转换的基础,我们需要将输入的n进制数先转换为计算机容易处理的十进制数。
-
将十进制数转换为m进制数:得到十进制结果后,我们再将其转换为目标进制m。
参考代码
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
char q[55], top; // 使用数组q作为栈存储转换后的数字,top表示栈顶
int main() {
int b, t, num = 0; // b:原始进制,t:目标进制,num:存储十进制结果
string n; // 存储输入的n进制数
cin >> b >> n >> t;
// 第一步:将n进制转换为十进制
int len = n.size();
for (int i = 0; i < len; i++) {
int m; // 当前位的数值
// 处理字母和数字两种情况
if (n[len - i - 1] >= 'A' && n[len - i - 1] <= 'F') {
m = n[len - i - 1] - 'A' + 10; // 将A-F转换为10-15
} else {
m = n[len - i - 1] - '0'; // 将字符数字转换为数值
}
num += (m * pow(b, i)); // 按位权展开求和
}
// 第二步:将十进制转换为m进制
if (t <= 10) {
// 目标进制≤10时,直接使用数字表示
while (num) {
q[++top] = num % t + '0'; // 取余得到当前位,转换为字符
num /= t; // 除以目标进制继续处理
}
} else {
// 目标进制>10时,需要处理字母表示
while (num) {
char c;
if (num % t >= 10)
c = num % t - 10 + 'A'; // 10-15转换为A-F
else
c = num % t + '0'; // 0-9直接转换为数字字符
q[++top] = c;
num /= t;
}
}
// 输出结果:从栈顶开始输出,实现逆序
while (top) {
cout << q[top--];
}
return 0;
}
关键点说明
-
进制转换原理:
-
n进制转十进制:按位权展开求和,即每一位的值乘以n的相应次方。
-
十进制转m进制:不断除以m取余数,最后将余数逆序排列。
-
-
字符处理:
-
输入时,A-F代表10-15,需要特殊处理。
-
输出时,根据目标进制决定是否使用字母表示。
-
-
逆序输出:
-
使用栈结构(这里用数组模拟)存储转换结果,因为进制转换得到的数字是逆序的。
-
复杂度分析
-
时间复杂度:O(len(n) + log(num)),其中len(n)是输入数字的长度,log(num)是十进制结果转换为m进制时的循环次数。
-
空间复杂度:O(1),使用了固定大小的数组存储结果。
示例验证
以题目中的样例为例:
-
输入:16(进制) FF(数字) 2(目标进制)
-
过程:
-
FF(16) = 15×16⁰ + 15×16¹ = 15 + 240 = 255(10)
-
255(10) = 11111111(2)
-
-
输出:11111111

浙公网安备 33010602011771号