【模板小程序】非负数2~62任意进制转换(普通版本+大数版本)

普通版本(区别于大数版本),包含合法性检查

  1 //进制转换模块
  2 #include <iostream>
  3 #include <string>
  4 #include <cmath>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 //将任意字符转换为十进制 [0-9a-zA-Z],61个字符,最大表示62进制
 10 int convertToDec(char c)
 11 {
 12     int decNum;
 13     if(c>='0' && c<='9')
 14         decNum=c-48;
 15     else if(c>='a' && c<='z')
 16         decNum=c-87;
 17     else if(c>='A' && c<='Z')
 18         decNum=c-29;
 19 
 20     return decNum;
 21 }
 22 
 23 //将十进制转换为这些字符 [0-9a-zA-Z],61个字符,最大表示62进制
 24 char convertFromDec(int c)
 25 {
 26     char objchar;
 27     if(c>=0 && c<=9)
 28         objchar=c+48;
 29     else if(c>=10 && c<=35)
 30         objchar=c+87;
 31     else if(c>=36 && c<=61)
 32         objchar=c+29;
 33 
 34     return objchar;
 35 }
 36 
 37 //从原进制转换为2~62的任意进制
 38 string convert(int src,int obj,string num_str)
 39 {
 40     //    string num_str=to_string(num);
 41     long long decNum=0;//十进制数(中间数)
 42     for(int i=0;i<(int)num_str.size();++i)
 43         decNum+=convertToDec(num_str[i])*pow(src,num_str.size()-1-i);
 44 
 45     string strTmp;
 46     long long tmp;
 47     while(decNum>0)
 48     {
 49         tmp=decNum % obj;
 50         strTmp=convertFromDec(tmp)+strTmp;
 51         decNum/=obj;
 52     }
 53     return strTmp;
 54 }
 55 
 56 //合法性检查,M为源进制
 57 bool IsVaild(const string& src_num,int M)
 58 {
 59     if(M>=2 && M<=10)//2-10进制
 60     {
 61         for(int i=0;i<(int)src_num.length();++i)
 62         {
 63             if(src_num[i]<'0' || src_num[i]-'0'>=M)
 64             {
 65                 return false;
 66             }
 67         }
 68     }
 69     else if(M>=11 && M<=36)
 70     {
 71         for(int i=0;i<(int)src_num.length();++i)
 72         {
 73             if(!((src_num[i]>='0' && src_num[i]-'0'<M)
 74                  ||  (src_num[i]>='a' && src_num[i]-'a'<M)))
 75             {
 76                 return false;
 77             }
 78         }
 79     }
 80     else if(M>=37 && M<=62)
 81     {
 82         for(int i=0;i<(int)src_num.length();++i)
 83         {
 84             if(!((src_num[i]>='0' && src_num[i]-'0'<M)
 85                  ||  (src_num[i]>='a' && src_num[i]-'a'<M)
 86                     ||(src_num[i]>='A' && src_num[i]-'A'<M)))
 87             {
 88                 return false;
 89             }
 90         }
 91     }
 92     return true;
 93 }
 94 
 95 //M进制转换为N进制,数字以string形式给出,需包含合法性检查
 96 int main()
 97 {
 98     int M,N;//M进制转换为N进制
 99     string src_num;//M进制的数
100     while(cin>>M>>N>>src_num)
101     {
102         //如果不超过36进制,大小写无所谓,可统一转换为小写
103         //transform(src_num.begin(),src_num.end(),src_num.begin(),::tolower);
104         if(!IsVaild(src_num,M))
105         {
106             cout<<"数据不合法"<<endl;
107             continue;
108         }
109         string obj_num;//N进制的数
110         obj_num=convert(M,N,src_num);
111         cout<<obj_num<<endl;
112     }
113     return 0;
114 }

大数版本(这个版本适用性更广泛,需要处理负数的话另外加个flag即可),未加入合法性检查

再来一个针对大数的版本,而且直接在源进制和目标进制之间转换(不需要先转换为10进制),可以说是十分厉害。参考了http://blog.csdn.net/jaster_wisdom/article/details/52107785的代码,并扩展至62进制,在此表示感谢。

 1 /*
 2 本程序说明:
 3 
 4 参考了http://blog.csdn.net/jaster_wisdom/article/details/52107785,并进行完善。
 5 大数2~62进制转换,只限于整数(负数可以提前去掉负号再用本程序处理)
 6 
 7 */
 8 
 9 #include <iostream>
10 #include <string>
11 #include <cstring>
12 
13 using namespace std;
14 
15 int main(){
16     int src,obj;//源进制和目标进制
17     string X;//待转换大数,用字符串处理
18     while(cin>>X>>src>>obj)
19     {
20         int data[1010];  //保存M进制下的各个位数
21         int output[1010];  //保存N进制下的各个位数
22         memset(output,0,sizeof(output));
23         for(int i=0;i<X.length();i++){
24             if(X[i]>='0' && X[i]<='9')
25                 data[i] = X[i] - '0';
26             else if(X[i]>='a' && X[i]<='z')
27                 data[i] = X[i] - 'a' + 10;
28             else if(X[i]>='A' && X[i]<='Z')
29                 data[i] = X[i] - 'A' + 36;
30 
31         }
32         int sum = 1;
33         int d  = 0;
34         int len = X.length();
35         int k = 0;
36         while(sum){
37             sum = 0;
38             for(int i=0;i<len;i++){
39                 d = data[i] / obj;
40                 sum += d;
41                 if(i == len-1){
42                     output[k++] = data[i] % obj;
43                 }
44                 else{
45                     data[i+1] += (data[i] % obj) * src;
46                 }
47                 data[i] = d;
48             }
49         }
50         if(k == 0){
51             output[k] = 0;
52             k--;
53         }
54         if(k == -1){
55             cout<<0<<endl;
56         }
57         else{
58             for(int i=0;i<k;i++){
59                 if(output[k-i-1] <=9)
60                     cout<<output[k-i-1];
61                 else if(output[k-i-1] <=35)
62                     cout<<(char)(output[k-i-1]+ 'a' - 10);
63                 else if(output[k-i-1] <=61)
64                     cout<<(char)(output[k-i-1]+ 'A' - 36);
65             }
66         }
67         cout<<endl;
68     }
69     return 0;
70 }

 大数版本的解释(同转载至以上链接):

『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』
原文地址:https://www.cnblogs.com/xiaoxi666/p/7255567.html