C++ 进制转换:通用 a 进制转 b 进制(2-36进制)题解

1. 问题分析

本题要求实现一个通用的进制转换器,能够将任意 a 进制(2 ≤ a ≤ 36)的数转换为 b 进制(2 ≤ b ≤ 36)的数。输入的数字可能包含字母(a-z 表示 10-35),输出也需要用字母表示大于 9 的数字。

核心思路是采用"以十进制为桥梁"的两步转换法:

  1. a 进制 → 十进制:将输入的 a 进制数按权展开,转换为十进制整数。
  2. 十进制 → b 进制:使用"除 b 取余法"将十进制整数转换为 b 进制数。

2. 算法设计

2.1 a 进制转十进制

遍历输入字符串的每一位:

  • 如果字符是 '0'-'9',则其数值为 ch - '0'。
  • 如果字符是 'a'-'z',则其数值为 ch - 'a' + 10。
  • 如果字符是 'A'-'Z',则其数值为 ch - 'A' + 10。

累加计算:decimal = decimal * a + digit_value。

2.2 十进制转 b 进制

使用循环,不断对十进制数进行取模和除法操作:

  • 取余数 decimal % b,得到当前最低位的数值。
  • 将余数转换为对应的字符(0-9 或 a-z)。
  • 将结果字符拼接到结果字符串的前面(或最后反转)。
  • 更新 decimal = decimal / b,直到 decimal 为 0。

3. 代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <algorithm> // for reverse
using namespace std;

// 将字符转换为对应的数值
int charToValue(char ch) {
    if (ch >= '0' && ch <= '9') {
        return ch - '0';
    } else if (ch >= 'a' && ch <= 'z') {
        return ch - 'a' + 10;
    } else if (ch >= 'A' && ch <= 'Z') {
        return ch - 'A' + 10;
    }
    return 0; // 不会发生
}

// 将数值转换为对应的字符
char valueToChar(int val) {
    if (val >= 0 && val <= 9) {
        return '0' + val;
    } else {
        return 'a' + (val - 10);
    }
}

int main() {
    int a, b;
    string num;
    cin >> a >> b;
    cin >> num;

    // Step 1: a进制 -> 十进制
    long long decimal = 0; // 使用 long long 防止溢出
    for (char ch : num) {
        decimal = decimal * a + charToValue(ch);
    }

    // Step 2: 十进制 -> b进制
    string result = "";
    if (decimal == 0) {
        result = "0";
    } else {
        while (decimal > 0) {
            result += valueToChar(decimal % b);
            decimal /= b;
        }
        reverse(result.begin(), result.end());
    }

    cout << result << endl;
    return 0;
}

4. 代码详解

  • charToValue 函数 :将字符 '0'-'9'、'a'-'z'、'A'-'Z' 统一转换为对应的整数值(0-35)。
  • valueToChar 函数:将整数值(0-35)转换回字符。题目要求输出小写字母,因此这里统一返回小写。
  • 数据类型 :使用 long long 来存储十进制中间结果,因为当 a 进制数位数较多时,十进制值可能超过 int 范围。
  • 特殊处理 :当输入为 "0" 时,直接输出 "0",避免 while 循环不执行导致结果为空。
  • 结果反转 :除 b 取余法 得到的是从低位到高位的顺序,最后需要用 reverse 反转得到正确顺序。

5. 测试样例

输入:

复制代码
16 32
abcdef

计算过程:

  1. abcdef (16进制) = 10*16^5 + 11*16^4 + 12*16^3 + 13*16^2 + 14*16^1 + 15*16^0 = 11259375 (十进制)
  2. 11259375 转换为 32 进制:
    • 11259375 % 32 = 15 → f
    • 351855 % 32 = 15 → f
    • 10995 % 32 = 19 → j
    • 343 % 32 = 23 → n
    • 10 % 32 = 10 → a
    • 0 % 32 = 0 → 0 (循环结束)
    • 反转得到:anjff

输出:

复制代码
anjff

与题目样例完全一致。

6. 总结

本题是进制转换的经典题型,核心在于理解"以十进制为桥梁"的转换思想。代码实现时需要注意:

  1. 字符与数值之间的正确映射。
  2. 使用 long long 避免整数溢出。
  3. 处理输入为 "0" 的特殊情况。
  4. 输出结果时注意大小写要求(本题要求小写)。

掌握了这个通用解法,就可以轻松应对 2-36 进制之间的任意转换问题了。

相关推荐
白帽攻防录10 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛10 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_9651481111 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
所以遗憾是什么呢?11 小时前
【题解】Educational Codeforces Round 195 (Rated for Div. 2) ABCDE
c++·动态规划·acm·icpc·ccpc·xcpc·codeforecs
xixiaoyunya12 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
学逆向的12 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
小坏讲微服务12 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
Lhan.zzZ13 小时前
Qt WebEngineView 在 Linux 上无法加载网页:从“看不见 HTML“到“禁用沙箱“
linux·c++·qt
打工仔折腾 AI14 小时前
用 Dashlet 把极空间 NAS 服务入口整理成统一导航首页的实践
java·开发语言·人工智能·后端·python·rpc·ai agent 实战
MATLAB代码顾问14 小时前
Simulink PI 参数扫描与批量仿真完整 MATLAB 代码
开发语言·matlab