天天看點

【模闆小程式】非負數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 }      

 大數版本的解釋(同轉載至以上連結):

【模闆小程式】非負數2~62任意進制轉換(普通版本+大數版本)

『注:本文來自部落格園“小溪的部落格”,若非聲明均為原創内容,請勿用于商業用途,轉載請注明出處http://www.cnblogs.com/xiaoxi666/』

繼續閱讀