洛谷B3869 [GESP202309 四级] 进制转换

一、原理

这段代码的主要功能是将不同进制(2 - 16 进制)的数转换为十进制数。其核心原理基于进制转换的基本规则:对于一个  进制数 ,将其按位展开,每一位的数值乘以  的相应次幂(幂次从右到左依次递增),然后将所有结果相加,就可以得到对应的十进制数。

二、步骤

  1. 字符转换函数 charToValue
    • 该函数接收一个字符 c 作为参数,用于将字符形式的数字转换为对应的数值。
    • 如果字符 c 是 0 到 9 之间的数字字符,通过 c - '0' 得到其对应的数值。
    • 如果字符 c 是 A 到 F 之间的大写字母,代表十六进制中的 10 到 15,通过 10 + (c - 'A') 得到其对应的数值。
    • 若输入的字符不符合上述规则,返回 0(在正常输入情况下,不会执行到这一步)。
  2. 进制转换函数 change
    • 该函数接收两个参数:一个整数 K 表示输入数字的进制,一个字符串 X 表示要转换的  进制数。
    • 初始化两个变量:result 用于存储最终的十进制结果,初始值为 0base 用于存储当前位的权值,初始值为 1(即 )。
    • 从字符串 X 的最后一位(最低位)开始,逐位向前遍历。
    • 对于每一位,调用 charToValue 函数将字符转换为对应的数值 digit
    • 将 digit 乘以当前位的权值 base,并累加到 result 中。
    • 更新 base 为下一位的权值,即 base *= K
    • 遍历结束后,返回 result,即转换后的十进制数。
  3. 主函数 main
    • 首先读取一个整数 N,表示要进行转换的数字个数。
    • 使用 for 循环进行 N 次转换操作。
    • 在每次循环中,读取一个整数 K 和一个字符串 X,分别表示当前数字的进制和该进制下的数字。
    • 调用 change 函数将 X 从  进制转换为十进制,并将结果输出。

三、图示法表示步骤(以将十六进制数 2A 转换为十进制为例,即 ,)

 

步骤操作详细说明
1初始化result = 0base = 1
2处理最低位 A 
 获取字符 A 对应的数值:调用 charToValue('A'),得到 10 
 计算当前位的值:10 * 1 = 10 
 更新 resultresult = 0 + 10 = 10 
 更新 basebase = 1 * 16 = 16 
3处理最高位 2 
 获取字符 2 对应的数值:调用 charToValue('2'),得到 2 
 计算当前位的值:2 * 16 = 32 
 更新 resultresult = 10 + 32 = 42 
 更新 basebase = 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 中包含不符合该进制的字符时,程序可能会出现错误的结果。可以添加相应的输入验证逻辑,提高代码的健壮性。
  • 功能拓展方面:代码仅实现了从其他进制到十进制的转换,如果需要实现十进制到其他进制的转换,或者更广泛的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值