【模板小程序】非负数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/』