数学问题——进制转换

Posted 牧空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数学问题——进制转换相关的知识,希望对你有一定的参考价值。

解法

就是基础的求模和整除运算,但一般都会涉及大整数的转换,所以要注意字符串的操作,当然十进制以上的就更不用说了
大数处理问题课参照我的另一篇博客——数学问题(二)——大数处理

例题

OJ链接

描述
将M进制的数X转换为N进制的数输出。
输入描述:
输入的第一行包括两个整数:M和N(2<=M,N<=36)。
下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。
输出描述:
输出X的N进制表示的数。
示例1
输入:
10 2
11
输出:
1011
备注:
注意输入时如有字母,则字母为大写,输出时如有字母,则字母为小写。

AC代码

#include <iostream>
#include <cstdio>
#include <string>
#include <map>

using namespace std;

map<char, int> char2num;
map<int, char> num2char;

/*
初始化模板
*/
void initMap()
{
    for (int i = 0; i < 10; i++)
    {
        char2num['0' + i] = i;
        num2char[i] = '0' + i;
    }
    for (int i = 0; i < 26; i++)
    {
        char2num['A' + i] = i + 10;
        num2char[i + 10] = 'a' + i;
    }
}

int main(int argc, char const *argv[])
{
    initMap();
    int M, N;
    cin >> M >> N;
    getchar();
    string number;
    cin >> number;
    long long num = 0;
    string result = "";
    for (int i = 0; i < number.size(); i++)
    {
        num *= M;
        num += char2num[number[i]];
    }
    while (num != 0)
    {
        int next = num % N;
        num /= N;
        result = num2char[next] + result;
    }
    cout << result << endl;
    return 0;
}

实际正解

因为平台的测试数据没有超出long long,所以上面的代码AC没有问题,但是如果数值超出long long显然会WA,所以需要引入大数的操作。进制的转换关键在大数的除法

此处我就复制粘贴了大佬的AC代码
代码来源牛客网该题第一个题解

#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
const int maxn = 600;//大数的最大位数
char str[maxn];//存储要转换的大数,以字符形式存储
//oldbase:原基数。newbase:新基数。len:大数的长度 pos:下标
int oldbase, newbase, len, pos;
//a[maxn]:储存大数的最小整型。注意a[0]没有使用;r[maxn]:储存余数,即所求数的每一位
int a[maxn],r[maxn];
//将字符转换成相应进制的整数
int getNum(char ch){
    if(isdigit(ch)) return ch - '0';
    else if(isupper(ch)) return ch - 'A' + 10;
    else return ch - 'a' + 36;
}
//将相应进制整数转换成相应的字符
char getChar(int i){
    if(i >= 0 && i <= 9) return i + '0';
    if(i >= 10 && i <= 35) return i - 10 + 'A';
    return i - 36 + 'A';
}
//调用函数将字符串转化成相应进制的整数。按位转化
void chToNum(){
    len = strlen(str);//测量字符串的长度
    //遍历每个字符,一一相应转换,注意没有使用a[0]
    for(int i = 1; i <= len; i++){
        a[i] = getNum(str[i - 1]);
    }
}
/*********************************
			核心
*********************************/
void conversion()//转化函数
{
    int i;
    pos = 0;
    for(i = 1; i <= len;){
        int j, k = 0;
        //对数的每一位除新基数求商求余
        for(j = i; j <= len; j++){
            k = k * oldbase + a[j];//计算除数
            a[j] = k / newbase;//求商
            k %= newbase;//求余
        }
        r[pos++] = k;//记录最后一个余数
        for(j = 1; j <= len && !a[j]; j++);//去除前导0
        i = j;
    }
}
//输出函数
void print()
{
    //逆序输出余数,即为结果
    while(pos--){
        printf("%c", getChar(r[pos]));
    }
    printf("\\n");
}
int main(){
    int n;
    scanf("%d %d %s", &oldbase, &newbase, str);
    chToNum();//字符串转换为整型
    conversion();//转化
    print();//函数调用输出结果
    return 0;
}

以上是关于数学问题——进制转换的主要内容,如果未能解决你的问题,请参考以下文章

数学问题——进制转换

c_cpp C片段将十进制转换为二进制

数学问题-进制转换

HDU4814——数学,模拟进制转换

如何将 RGB 输入转换为十进制颜色代码?

数学学习笔记