問題描述:將用字符串表示的M進制大數(shù),轉(zhuǎn)化為用字符串表示的N進制大數(shù)讼积。1<M,N<=62;字符串的取值為[0-9a-zA-Z]沐祷,例如B表示數(shù)字37。
1纵寝、受位數(shù)限制的方案
關(guān)于此問題论寨,最簡單的實現(xiàn)方式是先將M進制的大數(shù)轉(zhuǎn)化為long long類型的10進制整數(shù),然后再輾轉(zhuǎn)相除求出爽茴,N進制的大數(shù)字符串葬凳。
void reverse(string& srcNum){
size_t i = 0, j = srcNum.size() - 1;
char temp = 0;
while (i < j){
temp = srcNum[i];
srcNum[i++] = srcNum[j];
srcNum[j--] = temp;
}
}
string m2n_constrait(int srcBase, int desBase, string srcNum){
if (srcBase > 62 || srcBase < 2 || desBase > 62 || desBase < 2)
return "";
char flag[63] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string desNum;
long long midNum = 0, temp = 0;
for (size_t i = 0; i < srcNum.size(); ++i){
if (srcNum[i] >= '0' && srcNum[i] <= '9')
temp = srcNum[i] - '0';
else if (srcNum[i] >= 'a' && srcNum[i] <= 'z')
temp = srcNum[i] - 'a' + 10;
else if (srcNum[i] >= 'A' && srcNum[i] <= 'Z')
temp = srcNum[i] - 'A' + 36;
else return "";
midNum = midNum * srcBase + temp;
}
while (midNum){
desNum.push_back(flag[midNum % desBase]);
midNum /= desBase;
}
reverse(desNum);
return desNum;
}
2、通用方案
此方案直接對原數(shù)據(jù)室奏,用目標進制n直接進行輾轉(zhuǎn)相除火焰,取商和取余,逐步求解每一位最終結(jié)果胧沫。實現(xiàn)起來較為復(fù)雜昌简,下面以一個簡單的例子來說明其詳細過程:要求將32進制的45轉(zhuǎn)化為9進制的數(shù)字
- 判斷4是否大于9,不是绒怨,所以不進行輾轉(zhuǎn)除
- 4*32 + 5 = 133纯赎,此時大于9, 由于 133 mod 9 = 7, 133 / 9 = 14 (即e)南蹂;將e轉(zhuǎn)至中間結(jié)果
- 第一輪循環(huán)結(jié)束犬金,將上一步的余數(shù)7存至最終結(jié)果,進行下一輪轉(zhuǎn)化(此時轉(zhuǎn)化e)
- 判斷e是否大于9,將e / 9 = 1晚顷, e mod 9 = 5峰伙;將1存至中間變量
- 第二輪循環(huán)結(jié)束,將上一步的余數(shù)5存至最終結(jié)果该默,進行下一輪轉(zhuǎn)化(此時轉(zhuǎn)化1)
- 判斷1是否大于9瞳氓,由于1小于9,不再有中間結(jié)果
- 第三輪循環(huán)結(jié)束栓袖,將上一步的余數(shù)1存至最終結(jié)果
- 將最終結(jié)果751逆序顿膨,得到最終結(jié)果157
void reverse(string& srcNum){
size_t i = 0, j = srcNum.size() - 1;
char temp = 0;
while (i < j){
temp = srcNum[i];
srcNum[i++] = srcNum[j];
srcNum[j--] = temp;
}
}
bool isZero(string& srcNum){
for (size_t i = 0; i<srcNum.size(); ++i){
if (srcNum[i] != '0')
return false;
}
return true;
}
string m2n(int srcBase, int desBase, string srcNum){
if (srcBase > 62 || srcBase < 2 || desBase > 62 || desBase < 2)
return "";
char flag[63] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
string desNum, midNum;
long long temp = 0, carry = 0;
while (!srcNum.empty() && !isZero(srcNum) ){
for (size_t i = 0; i < srcNum.size(); ++i){
if (srcNum[i] >= '0' && srcNum[i] <= '9')
temp = srcNum[i] - '0';
else if (srcNum[i] >= 'a' && srcNum[i] <= 'z')
temp = srcNum[i] - 'a' + 10;
else if (srcNum[i] >= 'A' && srcNum[i] <= 'Z')
temp = srcNum[i] - 'A' + 36;
else return "";
carry = carry * srcBase + temp;
if (carry / desBase != 0 || i == srcNum.size() - 1){
midNum.push_back(flag[carry / desBase]);
carry %= desBase;
}
}
desNum.push_back(flag[carry]);
srcNum = midNum;
carry = 0;
midNum.clear();
}
reverse(desNum);
return desNum;
}