P1143 进制转换

问题概述

题目要求我们实现一个程序,将一个n进制的数转换为m进制的数。其中n和m的范围都是2到16,当进制大于10时,使用大写字母A-F表示10-15的数字。

解题思路

解决这个问题可以分为两个主要步骤:

  1. 将n进制数转换为十进制数:这是进制转换的基础,我们需要将输入的n进制数先转换为计算机容易处理的十进制数。

  2. 将十进制数转换为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;
}

关键点说明

  1. 进制转换原理

    • n进制转十进制:按位权展开求和,即每一位的值乘以n的相应次方。

    • 十进制转m进制:不断除以m取余数,最后将余数逆序排列。

  2. 字符处理

    • 输入时,A-F代表10-15,需要特殊处理。

    • 输出时,根据目标进制决定是否使用字母表示。

  3. 逆序输出

    • 使用栈结构(这里用数组模拟)存储转换结果,因为进制转换得到的数字是逆序的。

复杂度分析

  • 时间复杂度:O(len(n) + log(num)),其中len(n)是输入数字的长度,log(num)是十进制结果转换为m进制时的循环次数。

  • 空间复杂度:O(1),使用了固定大小的数组存储结果。

示例验证

以题目中的样例为例:

  • 输入:16(进制) FF(数字) 2(目标进制)

  • 过程:

    1. FF(16) = 15×16⁰ + 15×16¹ = 15 + 240 = 255(10)

    2. 255(10) = 11111111(2)

  • 输出:11111111

posted @ 2025-05-19 15:17  行胜于言Ibl  阅读(59)  评论(0)    收藏  举报