这道题综合性极强,囊括了“BigInt+BigInt”“BigInt*int”“BigInt/int”“BigInt%int”四个高精度整数的基本操作,以及“输入n进制串化为高精度整数”“高精度整数的进制转换”等问题。
-
将M进制的数X转换为N进制的数输出。
算法分析:
误区:
①权值以及string的某位乘值可能会变得非常大,int存不下。
②当M进制to十进制时,想用string逐位乘权值(int)→(得)某位和(int)→(按digit[]逐位存)十进制的和(BigInt)。这样由于每次乘都可能导致十进制和(BigInt)的每位都发生变化,难以实现。
改正:采用string逐位乘权值(BigInt)→(得)BigInt→(与十进制和加和,储存在)十进制和(BigInt)
①改用BigInt存权值,用BigInt存某位和,解决了问题①
②用逐位乘后累加在最终结果(BigInt)中,代替了按digit[]逐位存,解决了问题②
Debug记录:
①在int2BigInt()函数中要考虑到输入为0的情况,使用do while循环
void int2BigInt(int x){
initBigInt();
do{//注意这里与n进制化成十进制一样,也要考虑x=0的情况 ********
digit[intSize]=x%10000;
intSize++;
x/=10000;
}while (x>0);
}
②在函数中要注意被除数输入为0的情况的处理:在对answer的intSize赋值时,光有"answer.digit[intSize-1]==0?"这个判断条件还不够,因为可能出现输入为0的情况,但此时intSize不应该被赋值0,因为数0是占有一位的。故要同时满足intSize!=1(即输入的被除数并不是一位数)的条件,以排除掉输入0的情况。(可以枚举四种情况分析后 确认该表达式正确)
BigInt operator/(const int x)const{//x<10000
BigInt answer;
answer.initBigInt();
int c=0;
for (int i=intSize-1;i>=0;i--){
answer.digit[i]=digit[i]+c*10000;
c=answer.digit[i]%x;
answer.digit[i]/=x;
}
answer.intSize=intSize!=1&&answer.digit[intSize-1]==0?intSize-1:intSize;//*****注意intSize!=1这个判断条件
return answer;
}
③在十进制化为n进制用stack存数的循环上,也得用do while 来应付输入为0的情况
//10 to n
do{//至少做一次以防x=0时空栈 //****
c=x%n;
x=x/n;
sta.push(c);
} while (!(x.digit[0]==0&&x.intSize==1));
题目描述:
-
输入:
-
输入的第一行包括两个整数:M和N(2<=M,N<=36)。
下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。
-
输出:
-
输出X的N进制表示的数。
-
样例输入:
-
16 10 F
-
样例输出:
-
15
-
提示:
-
输入时字母部分为大写,输出时为小写,并且有大数据。
-
答疑:
- 解题遇到问题?分享解题心得?讨论本题请访问: http://t.jobdu.com/thread-7803-1-1.html
#include <iostream>
#include <cstring>
#include <stack>
#include <iomanip>
#define MAXSIZE 1000
using namespace std;
struct BigInt{
int digit[MAXSIZE];
int intSize;
void initBigInt(){
for (int i=0;i<MAXSIZE;i++)
digit[i]=0;
intSize=0;
}
void int2BigInt(int x){
initBigInt();
while (x>0){
digit[intSize]=x%10000;
intSize++;
x/=10000;
}
}
void char2BigInt(char *s){
initBigInt();
int weight;
for (int i=strlen(s)-1;i>=0;i-=4){
weight=1;
for (int j=i;j>i-4&&j>=0;j--){
digit[intSize]+=(s[j]-'0')*weight;
weight*=10;
}
intSize++;
}
}
BigInt operator+(const BigInt &a)const{
BigInt sum;
sum.initBigInt();
int c=0;
int i;
for (i=0;i<intSize||i<a.intSize;i++){
sum.digit[i]=c+digit[i]+a.digit[i];
c=sum.digit[i]/10000;
sum.digit[i]%=10000;
}
sum.intSize=i;
if (c!=0)
sum.digit[sum.intSize++]=c;
return sum;
}
BigInt operator*(int x)const{
BigInt pro;
pro.initBigInt();
int c=0;
int i;
for (i=0;i<intSize;i++){
pro.digit[i]=digit[i]*x+c;
c=pro.digit[i]/10000;
pro.digit[i]%=10000;
}
pro.intSize=i;
while (c>0){
pro.digit[pro.intSize++]=c%10000;
c/=10000;
}
return pro;
}
BigInt operator/(const int x)const{//x<10000
BigInt answer;
answer.initBigInt();
int c=0;
for (int i=intSize-1;i>=0;i--){
answer.digit[i]=digit[i]+c*10000;
c=answer.digit[i]%x;
answer.digit[i]/=x;
}
answer.intSize=intSize!=1&&answer.digit[intSize-1]==0?intSize-1:intSize;//*****注意intSize!=1这个判断条件
return answer;
}
int operator%(const int x)const{//x<10000
int temp,c=0;
for (int i=intSize-1;i>=0;i--){
temp=digit[i]+c*10000;
c=temp%x;
}
return c;
}
void print(){
for (int i=intSize-1;i>=0;i--){
cout<<setfill('0')<<setw(i==intSize-1?0:4)<<digit[i];
}
cout<<endl;
}
};
int main(){
int m,n;
char s[1000];
BigInt weight,x;
int temp,c;
stack<int> sta;
while (cin>>m>>n){
//initiate
weight.int2BigInt(1);
x.initBigInt();
cin>>s;
//m to 10
for (int i=strlen(s)-1;i>=0;i--){
temp=s[i]-('0'<=s[i]&&s[i]<='9'?'0':'A'-10);
x=x+weight*temp;
weight=weight*m;
}
//10 to n
do{//至少做一次以防x=0时空栈 //****
c=x%n;
x=x/n;
sta.push(c);
} while (!(x.digit[0]==0&&x.intSize==1));
//output
while (!sta.empty()){
int p;
p=sta.top();
if (0<=p&&p<=9)
cout<<p;
else
cout<<(char)(p-10+'a');
sta.pop();
}
cout<<endl;
}
return true;
}