王道计算机机试练习——高精度大整数随意进制换算
题目描述
将 M 进制的数 X 转换为 N 进制的数输出。
输入: 输入的第一行包括两个整数: M 和 N(2<=M,N<=36) 。 下面的一行输入一个数 X,X 是 M 进制的数,现在要求你将 M 进制的数 X 转换成 N 进制的数输出。
输出: 输出 X 的 N 进制表示的数。
题目思路
该题初看起来很像一般的进制转换,但提示中明确告知,输入会有较大的数 据,即我们为了完成本例需要的进制转换,需要使用高精度整数。同时,考虑到 进制转换的内容,我们的高精度整数需要进行以下运算:高精度整数与普通整数 的求积,高精度整数之间求和,高精度整数除以普通整数,高精度整数对普通整 数求模等。
代码
#include<stdio.h>
#include<iostream>
#include<string>
#define maxDigits 100
struct bigInteger {//高精度整数结构体
int digit[maxDigits];
int size;
void init() {//初始化
for (int i = 0; i < maxDigits; i++) digit[i] = 0;
size = 0;
}
void set(int x) {//用一个普通整数初始化高精度整数
init();
do {
digit[size++] = x % 10000;
x /= 10000;
} while (x != 0);
}
void output() {//输出
for (int i = size - 1; i >= 0; i--) {
if (i != size - 1) printf("%04d", digit[i]);
else printf("%d", digit[i]);
}
printf("\n");
}
bigInteger operator*(int x) const {//高精度整数与普通整数的乘积
bigInteger ret;
ret.init();
int carry = 0;
for (int i = 0; i < size; i++) {
int tmp = x * digit[i] + carry;
carry = tmp / 10000;
tmp %= 10000;
ret.digit[ret.size++] = tmp;
}
if (carry != 0) {
ret.digit[ret.size++] = carry;
}
return ret;
}
bigInteger operator +(const bigInteger& A)const {//高精度整数之间的加法运算
bigInteger ret;
ret.init();
int carry = 0;
for (int i = 0; i < A.size || i < size; i++) {
int tmp = A.digit[i] + digit[i] + carry;
carry = tmp / 10000;
tmp %= 10000;
ret.digit[ret.size++] = tmp;
}
if (carry != 0) {
ret.digit[ret.size++] = carry;
}
return ret;
}
bigInteger operator /(int x)const {//高精度整数除以普通数
bigInteger ret;//返回的高精度整数
ret.init();
int remainder = 0;//余数
for (int i = size - 1; i >= 0; i--) {//从最高位至最低位依次计算
int t = (remainder * 10000 + digit[i]) / x;//计算当前位数值加上高位剩余的余数的和对x求得的商
int r = (remainder * 10000 + digit[i]) % x;//求余
ret.digit[i] = t;
remainder = r;
}
ret.size = 0;
for (int i = 0; i < maxDigits; i++) {
if (digit[i] != 0)ret.size = i;
}//若存在非零位,确定最高的非零位作为最高有效位
ret.size++;
return ret;
}
int operator %(int x)const {//高精度整数对普通整数求余数
int remainder = 0;
for (int i = size - 1; i >= 0; i--) {
int t = (remainder * 10000 + digit[i]) / x;
int r = (remainder * 10000 + digit[i]) / x;
remainder = r;
}
return remainder;//返回余数
}
}a,b,c;
char str[10000];
char ans[10000];
int main() {
int n, m;
while (scanf("%d%d", &m, &n) != EOF) {
scanf("%s",str);//输入m进制数
int L = strlen(str);
a.set(0);
b.set(1);
for (int i = L - 1; i >= 0; i--) {//由低位到高位转换m进制到十进制
int t = 0;
if (str[i] >= '0' && str[i] <= '9') {
t = str[i] - '0';
}
else {
t = str[i] - 'A' + 10;//确定当前位字符代表的数字
}
a = a + b * t;
b = b * m;
}
int size = 0;
do {//对转换后的十进制求其n进制的值
int t = a % n;//求余数
if (t >= 10)ans[size++] = t - 10 + 'a';
else ans[size++] = t + '0';//确定当前字符
a =a/n;
} while (a.digit[0] != 0 || a.size != 1);
for (int i = size - 1; i >= 0; i--) printf("%c", ans[i]);
printf("\n");
}
return 0;
}