如何实现一个任意进制转换的方法
我们在平时生活中通常会遇到 10 进制转其他进制,或其他进制转为 10 进制,那我们就可以通过 10 进制进行中转,实现各种任意进制的转换。
大部分编程语言都仅限在 2-36 进制内的转换,这里我们拓展到 62 进制,即小写字母
z
的下一位用大写字母
A
表示,直到大写字母
Z
。
我们先来熟悉下 10 进制之间的转换,然后进行统一。
1. 其他进制转为 10 进制
其他进制转为 10 进制时,将当前的基数乘以当前的位权,然后全部相加即可,如一个 8 进制的数字 123:
COPY SHELL
123 = 1 * 8^2 + 2 * 8^1 + 3 * 8^0;
= ((1 * 8) + 2) * 8 + 3;
通过这个简单的推导,我们在用代码实现时,可以从左到右,先用当前数字乘以进制,然后再参与下一位的运算,直到结束。
进制超过 10 时,会出现字母,这里我们需要把字母转为数字再进行计算。
字母转为数字:
COPY CPP
/**
* 将letter转为纯数字
* @param {char} letter
* @return {int}
int transformCharToNum(char letter)
if (letter >= '0' && letter <= '9')
return letter - '0';
if (letter >= 'a' && letter <= 'z')
return letter - 'a' + 10;
if (letter >= 'A' && letter <= 'Z')
return letter - 'A' + 36;
return 0;
}
其他进制转为 10 进制的具体实现:
COPY CPP
/**
* 将进制为base的字符串数字num,转为10进制的数字
* @param {string} num 要转换的数字
* @param {int} base 该数字的进制
int covertOtherTo10(string num, int base)
int p = 0, number10 = 0;
while (p < num.length())
number10 *= base;
number10 += transformCharToNum(num[p]); // 将字母转为纯数字,然后参与运算
return number10;
}
使用方式:
COPY CPP
covertOtherTo10("1101", 2); // 将2进制的数字1101转为10进制,结果为13
covertOtherTo10("2e", 16); // 将16进制的数字2e转为10进制,结果为46
2. 10 进制转为其他进制
10 进制的数字转为其他进制的数字,我们用到的短除法,即对某进制取余,获取到的余数即为该位置的基数。
转换后的进制可能比较大,如在 16 进制中,a 表示 10,b 表示 11 等,这里我们要有一个数字到字母的对照表。
我们用 C++ 来实现下:
COPY CPP
/**
* 将数字转为进制里的字母
* @param {int} num
* @return {char}
int transformNumToChar(int num)
string str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
return str[num];
}
10 进制转为其他进制的具体实现:
COPY CPP
string covert10ToOther(int num, int to) {
int cur;
string result;
while (num) {
cur = num % to;
result.push_back(transformNumToChar(cur)); // 将数组转为字母,如10->a
num /= to;
reverse(result.begin(), result.end());
return result;
}
使用方式:
COPY CPP
covert10ToOther(13, 2); // 将10进制里的13转为2进制,结果为1101
covert10ToOther(7, 2); // 111
covert10ToOther(13, 5); // 23
3. 任意进制转任意进制
任意进制之间的转换,我们只需要把上面的两种方式组合在一起就行了。这里中间需要 10 进制中转一下。
我们将进制转换扩展到了 62 进制,里面可能会包含英文字符,因此我们的输入和输出都定义成了 string 类型。若您需要的是纯数字格式的,还请自行转换。
COPY CPP
class Solution
public:
* 将num从base进制转为to指定的进制
* @param {string} num 要转换的数字字符串
* @param {int} base num的进制
* @param {int} to 转换后的进制
* @return {string}
string covert(string num, int base, int to)
// 当base和to相等 或 base和to超出转换范围,则原样返回
if (base == to || !this->checkRadixLegal(base) || !this->checkRadixLegal(to))
return num;
// 先转成10进制
int p = 0, number10 = 0;
while (p < num.length())
number10 *= base;
number10 += this->transformCharToNum(num[p]);
// 若要转换的正好是进制,则直接返回
if (to == 10) {
return to_string(number10);
int cur;
string result;
while (number10) {
cur = number10 % to;
result.push_back(this->transformNumToChar(cur));
number10 /= to;
reverse(result.begin(), result.end());
return result;
private:
bool checkRadixLegal(int radix)
return radix >= 2 && radix <= 62;
* 将letter转为纯数字
* @param {char} letter
* @return {int}
int transformCharToNum(char letter)
if (letter >= '0' && letter <= '9')
return letter - '0';
if (letter >= 'a' && letter <= 'z')
return letter - 'a' + 10;
if (letter >= 'A' && letter <= 'Z')
return letter - 'A' + 36;
return 0;
* 将数字转为进制里的字母
* @param {int} num
* @return {char}
int transformNumToChar(int num)
string str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
return str[num];
};
我们将进制扩展到了 62 进制内的任意进制,因此输入和输出均为 string 类型。
使用方式:
COPY CPP
auto aa = new Solution();
cout << aa->covert("1101", 2, 10); // "1101"为2进制数字,将其转为10进制,结果为13
cout << aa->covert("13", 10, 5) << endl;
cout << aa->covert("7", 10, 2) << endl;
cout << aa->covert("1101", 2, 16) << endl;
cout << aa->covert("456", 7, 2) << endl;
cout << aa->covert("2e", 16, 10) << endl;
cout << aa->covert("7aZ", 62, 10) << endl;
1101 from 2 to 10 is 13
13 from 10 to 5 is 23
7 from 10 to 2 is 111
1101 from 2 to 16 is d
456 from 7 to 2 is 11101101
2e from 16 to 10 is 46
7aZ from 62 to 10 is 27589
*/
我们就可以在 62 进制内实现任意进制的任意转换了。
4. JavaScript 中任意进制的转换
在 JavaScript 中,有两个系统方法 parseInt 和 toString,综合运用这两个方法,可以实现
36进制
内的任意进制的转换。
parseInt(string, radix): 将任意进制 radix(36 进制内)转为 10 进制的数字,radix 表示 string 本身是多少进制的;
num.toString(radix): 将 10 进制的数字转为任意进制 radix 的字符串,radix 表示要转换成多少进制的;
我们这里来封装一下:
COPY JAVASCRIPT
const covert = (num: string, base: number, to: number) => {
return parseInt(num, base).toString(to);
};
使用方式与上面的 C++代码实现的方式一样:
COPY JAVASCRIPT
covert('1101', 2, 10); // 13
covert('13', 10, 5); // 23
covert('2e', 16, 10); // 46
若需要扩展到更大的进制范围,就得需要自行实现了,具体实现方式可以参考上面 C++的代码。
algorithm
阅读(723)