1. 程式人生 > >九度OJ-1208:10進位制 VS 2進位制

九度OJ-1208:10進位制 VS 2進位制

  本題使用了寫好的高精度整數的模板,將ten2N()函式的輸出方式稍微改了改。

debug過程:

①過載的*運算通過這道題發現了bug:當輸入的int x為0時,由於使用的是BigInt與int逐位乘的演算法,故若BigInt的intSize不為1的話,會return一個值為0但intSize!=0的BigInt物件(這種BigInt物件是不能容忍的)導致出錯。故加入了修正程式碼,修改後如下:

	BigInt operator*(int x)const{//contain int2BigInt()
		BigInt pro;
		pro.initBigInt();
/*look here*/	if (x==0){	//防止當x=0時return一個值為0但intSize!=0的BigInt 
			pro.int2BigInt(0); 				
			return pro;			
		}
		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轉化為二進位制時,使用了儲存輸入的s串再對這次輸出進行儲存。而題目說輸入的十進位制數位數<=1000,極限情況時其轉化的二進位制串遠大於1000,此時便會發生陣列越界。故要擴大s的容量。
int main(){
	char s[5000];//bug****


題目描述:

    對於一個十進位制數A,將A轉換為二進位制數,然後按位逆序排列,再轉換為十進位制數B,我們乘B為A的二進位制逆序數。
    例如對於十進位制數173,它的二進位制形式為10101101,逆序排列得到10110101,其十進位制數為181,181即為173的二進位制逆序數。

輸入:

    一個1000位(即10^999)以內的十進位制數。

輸出:

    輸入的十進位制數的二進位制逆序數。

樣例輸入:
173
樣例輸出:
181

#include <iostream>
#include <cstring>
#include <iomanip>
#define MAXSIZE 1000
using namespace std;
struct BigInt{
	int digit[MAXSIZE];
	int intSize;
	void initBigInt(){//初值不為0,而是NULL(intSize=0) 
		for (int i=0;i<MAXSIZE;i++)
			digit[i]=0;
		intSize=0;
	} 
	void int2BigInt(int x){
		initBigInt();
		do{//注意這裡與n進位制化成十進位制一樣,也要考慮x=0的情況 ********
			digit[intSize]=x%10000;
			intSize++;
			x/=10000;
		}while (x>0);
	}
	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();
		if (x==0){				//
			pro.int2BigInt(0); 	//			
			return pro;			//bug****
		}
		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才能排除掉輸入本身即為0的情況,
		//否則輸入為0的話會出現answer.intSizse=0的錯誤賦值。 
		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;
	}
	
}; 

void m2Ten(char *s,int m,BigInt &x){//s[] is the number inputed,switch m to 10,store the answer in x
	BigInt weight;
	x.initBigInt();
	weight.int2BigInt(1);
	int temp;
	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;
	}
}
void ten2N(BigInt &x,int n,char *s){//the decimal num is in x,switch 10 to n,store the output in stack 
	int c;
	int len=0;
	do{//至少做一次以防x=0時空棧 //****
		c=x%n;
		x=x/n;
		s[len]=c+'0';
		len++;
	} while (!(x.digit[0]==0&&x.intSize==1));
	s[len]='\0';
}

int main(){
	char s[5000];//bug****
	BigInt x;
	while (cin>>s){
		//initiate
		x.char2BigInt(s);
		//process
		ten2N(x,2,s);
		m2Ten(s,2,x);
		//output 
		x.print();
	}
	return true;
}