任意机制之间整数转换-C++源码
任意进制间整数转换-C++源码
转换思路
仿照初中所学的10进制与2进制之间的转换方法,从低位依次往高位求余数即可。例如10进制110转换到2进制:
除数 | 被除数 ...... 余数
2 | 110 ...... 0
2 | 55 ...... 1
2 | 27 ...... 1
2 | 13 ...... 1
2 | 6 ...... 0
2 | 3 ...... 1
2 | 1 ...... 1
2 | 0 ...... 0
观察上述求解过程发现,p进制的被除数110除以q进制的除数2,得出了p进制的商55以及q进制的余数0。对这个过程进行归纳可以编写出如下代码。
具体代码思路
1.建立数值与字母之间映射关系
-
接收的数字可能是大整数,无法用常规的int来表示,那么就需要以字符串来接收输入的值。所以第一步需要建立int与char之间的映射关系,代码如下:
// 此处假设只使用数字0-9,大写字母A-Z。如果需要使用小写字母,自己扩展一下映射数组就可 void map_chr_int(){ for (char i = '0'; i <= '9'; ++i) chr2int[i] = i - '0'; for (char i = 'A'; i <= 'Z'; ++i) chr2int[i] = (i - 'A') + 10; for (int i = 0; i < 10; ++i) int2chr[i] = i + '0'; for (int i = 10; i < 36; ++i) int2chr[i] = (i - 10) + 'A'; }
2. 编写从p进制转换为q进制的函数
-
对于已经获取的p进制数,计算转换后的q进制数
void p2q(int p, int q){ if (p == q){ cout << original << endl; return; } int i, j = 0; int tmp_bfo; // 记录前一位的余数信息 int len = strlen(original); memset(ans, 0, sizeof(ans)); while(1){ i = 0; while (original[i] == '0') ++i; // 从p进制不为0的最高位开始除 if (i == len) break; // 已经全部转换完 tmp_bfo = 0; // 第一个不为0的位置,它前一位的余数为0 while (i < len){ // 计算除以q的余数 tmp_bfo = tmp_bfo * p + chr2int[original[i]]; // 计算p进制数在当前位置的数值 original[i++] = int2chr[tmp_bfo / q]; // 该数值除以q,得到p进制在该位置的新值 tmp_bfo %= q; // 该数值模q,得到p进制在该位置的新余数 } ans[j++] = tmp_bfo; } --j; for (; j >= 0; --j) cout << int2chr[ans[j]]; cout << endl; }
3. 全部代码
-
全部代码
#include <iostream> #include <string.h> using namespace std; int chr2int[100]; // int('Z') = 90;char 到 int 的映射 char int2chr[36]; // int 到 char 的映射 char original[55]; // 待转换字符串 int ans[255]; // 转换后的结果 void map_chr_int(){ for (char i = '0'; i <= '9'; ++i) chr2int[i] = i - '0'; for (char i = 'A'; i <= 'Z'; ++i) chr2int[i] = (i - 'A') + 10; for (int i = 0; i < 10; ++i) int2chr[i] = i + '0'; for (int i = 10; i < 36; ++i) int2chr[i] = (i - 10) + 'A'; } void p2q(int p, int q){ if (p == q){ cout << original << endl; return; } int i, j = 0; int tmp_bfo; // 记录前一位的余数信息 int len = strlen(original); memset(ans, 0, sizeof(ans)); while(1){ i = 0; while (original[i] == '0') ++i; if (i == len) break; // 已经全部计算完 tmp_bfo = 0; // 第一个不为0的位置,它前一位的余数为0 while (i < len){ tmp_bfo = tmp_bfo * p + chr2int[original[i]]; original[i++] = int2chr[tmp_bfo / q]; tmp_bfo %= q; } ans[j++] = tmp_bfo; } --j; for (; j >= 0; --j) cout << int2chr[ans[j]]; cout << endl; } int main() { map_chr_int(); int m, p, q; char c; cin >> m; while (m--){ cin >> p >> c; int i = 0; while (cin >> c && c != ',') original[i++] = c; original[i] = '\0'; cin >> q; p2q(p, q); } return 0; }
测试样例
首先输入一个正整数m,代表测试样例的个数
接着输入m行,每行三个’数‘,第一个数代表当前进制,第二个数代表数值,第三个数代表待转换进制
input:
6
18,2345678A123,18
15,23456,18
12,2345678,20
16,12345678,23
25,3456AB,21
18,AB1234567,22
输出:直接输出转换后的结果,每行一个结果
output
2345678A123
114E0
22B7A4
21A976L
7C2136
22JF0G367
总结
第一步需要理解进制转换的时候,除数与余数之间的转换过程。其次由于使用到了字母来代替10进制以上的数,以及可能会碰到比较大的整数,所以统一用字符串来接收输入的整数,因此需要建立数值到字母之间的转换关系。解决了这两个关键问题之后,剩下的就是整理思路,编写可靠的代码了。
码字不易,如果您觉得有帮助的话,请支持一下作者。