九度OJ-1208:10進位制 VS 2進位制
阿新 • • 發佈:2019-01-06
本題使用了寫好的高精度整數的模板,將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; }