数学问题——进制转换
Posted 牧空
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数学问题——进制转换相关的知识,希望对你有一定的参考价值。
解法
就是基础的求模和整除运算,但一般都会涉及大整数的转换,所以要注意字符串的操作,当然十进制以上的就更不用说了
大数处理问题课参照我的另一篇博客——数学问题(二)——大数处理
例题
描述
将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;
}
以上是关于数学问题——进制转换的主要内容,如果未能解决你的问题,请参考以下文章