九度OJ-1080:进制转换

  这道题综合性极强,囊括了“BigInt+BigInt”“BigInt*int”“BigInt/int”“BigInt%int”四个高精度整数的基本操作,以及“输入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进制的数X转换为N进制的数输出。

输入:

输入的第一行包括两个整数:M和N(2<=M,N<=36)。
下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。

输出:

输出X的N进制表示的数。

样例输入:
16 10
F
样例输出:
15
提示:

输入时字母部分为大写,输出时为小写,并且有大数据。

来源:
2008年清华大学计算机研究生机试真题
答疑:
解题遇到问题?分享解题心得?讨论本题请访问: 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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值