任意机制之间整数转换-C++源码

任意进制间整数转换-C++源码

  • 转换思路
  • 具体代码思路
    • 1.建立数值与字母之间映射关系
    • 2. 编写从p进制转换为q进制的函数
    • 3. 全部代码
  • 测试样例
  • 总结

转换思路

仿照初中所学的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.建立数值与字母之间映射关系

  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进制的函数

  1. 对于已经获取的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. 全部代码

  1. 全部代码

    #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进制以上的数,以及可能会碰到比较大的整数,所以统一用字符串来接收输入的整数,因此需要建立数值到字母之间的转换关系。解决了这两个关键问题之后,剩下的就是整理思路,编写可靠的代码了。

你可能感兴趣的:(算法设计)