首页 > 编程语言 >数的进制转换【《算法竞赛进阶指南》】

数的进制转换【《算法竞赛进阶指南》】

时间:2023-02-27 16:56:09浏览次数:47  
标签:10 进阶 string s1 v1 算法 输入 进制

数的进制转换

编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。

这里有 62 个不同数位 {0−9,A−Z,a−z}。

输入格式
第一行输入一个整数,代表接下来的行数。

接下来每一行都包含三个数字,首先是输入进制(十进制表示),然后是输出进制(十进制表示),最后是用输入进制表示的输入数字,数字之间用空格隔开。

输入进制和输出进制都在 2 到 62 的范围之内。

(在十进制下)A=10,B=11,…,Z=35,a=36,b=37,…,z=61 (0−9 仍然表示 0−9)。

输出格式
对于每一组进制转换,程序的输出都由三行构成。

第一行包含两个数字,首先是输入进制(十进制表示),然后是用输入进制表示的输入数字。

第二行包含两个数字,首先是输出进制(十进制表示),然后是用输出进制表示的输入数字。

第三行为空白行。

同一行内数字用空格隔开。

输入样例:
8
62 2 abcdefghiz
10 16 1234567890123456789012345678901234567890
16 35 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 23 333YMHOUE8JPLT7OX6K9FYCQ8A
23 49 946B9AA02MI37E3D3MMJ4G7BL2F05
49 61 1VbDkSIMJL3JjRgAdlUfcaWj
61 5 dl9MDSWqwHjDnToKcsWE1S
5 10 42104444441001414401221302402201233340311104212022133030
输出样例:
62 abcdefghiz
2 11011100000100010111110010010110011111001001100011010010001

10 1234567890123456789012345678901234567890
16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2

16 3A0C92075C0DBF3B8ACBC5F96CE3F0AD2
35 333YMHOUE8JPLT7OX6K9FYCQ8A

35 333YMHOUE8JPLT7OX6K9FYCQ8A
23 946B9AA02MI37E3D3MMJ4G7BL2F05

23 946B9AA02MI37E3D3MMJ4G7BL2F05
49 1VbDkSIMJL3JjRgAdlUfcaWj

49 1VbDkSIMJL3JjRgAdlUfcaWj
61 dl9MDSWqwHjDnToKcsWE1S

61 dl9MDSWqwHjDnToKcsWE1S
5 42104444441001414401221302402201233340311104212022133030

5 42104444441001414401221302402201233340311104212022133030
10 1234567890123456789012345678901234567890

思路

朴素做法:将读入进来的数转换成10进制,再将其转换成所需进制
观察将数转换成所需进制的过程, 发现确定每一位数时只需要得到这个数除以所需进制数的余数即可。
由于一个数不论以何种进制表示,其除以一个数的余数都是一样的。
所以可以直接将某进制的数除以另一进制的进制数,以此得到余数,构建所需进制的数。
注意本题需要高精度维护

ccytpe头文件

isdigit(x)判断字符是否为数字
isupper(x)判断字符是否为大写字母
islower(x)判断字符是否为小写字母

代码

点击查看代码
#include<iostream>
#include<vector>//注意要加头文件
#include<algorithm>
#include<cctype>
using namespace std;
const char nl = '\n';
//string s1;
string change(int a,string s1,int b){     //string也可以作为函数返回值
    vector<int> v1,v2;
    string s2;  //初始化
    // for(int i = 0; i <= s1.size() - 1; i ++ ){
    //     if(s1[i] >= '0' && s1[i] <= '9')v1.push_back(s1[i]-'0');
    //     else if(s1[i] >= 'A' && s1[i] <= 'Z')v1.push_back(s1[i]-'A'+10);
    //     else v1.push_back(s1[i]-'a'+36);    //共26个字母
    // }
    for(auto x:s1){
        if(isdigit(x))v1.push_back(x-'0');
        else if(isupper(x))v1.push_back(x-'A'+10);
        else v1.push_back(x-'a'+36);
    }
    //模拟求余数的过程
    
    reverse(v1.begin(),v1.end());   //使最高位在vector的后面,方便去除前导零
    while(v1.size()){
        int r = 0;	//保存余数
        for(int i = v1.size() - 1; i >= 0; i -- ){  //计算从最高位开始
            int t = v1[i] + r * a;   //更新用来计算的值(因为是a进制所以要乘a,类比10进制中药要乘10)
            r = t % b;	//新余数
            v1[i] = t / b;	//更新值(除到v1为空,即为0)
        }
        v2.push_back(r);
        while(!v1.back() && v1.size())v1.pop_back();    //去除前导0防止死循环
    }
    reverse(v2.begin(),v2.end());   //再次逆转得到正序数
    //还原
    for(auto x:v2){ 
        if(x >= 0 && x <= 9)s2 += x + '0';  
        //如果直接用s[cnt++]赋值的话(使用下标访问的值大于s.size())会出现不可预料的后果
        //如:s.empty()始终为空,s.size()始终为0,即cout << s2 << nl;输出为空白
        else if(x >= 10 && x <= 35)s2 += x - 10 + 'A';
        else s2 += x - 36 + 'a'; 
    }
    return s2;
}

int main(){
    int m;
    cin >> m;
    while(m -- ){
        int a,b;
        string s1;
        cin >> a >> b >> s1;
        cout << a << " " << s1 << nl;
        cout << b << " " << change(a,s1,b) << nl;
        cout << nl;
    }
}

标签:10,进阶,string,s1,v1,算法,输入,进制
From: https://www.cnblogs.com/J-12045/p/17160359.html

相关文章