您的位置:首页 > 移动开发 > 微信开发

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

2017-07-29 12:45 369 查看

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

//进制转换模块
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;

//将任意字符转换为十进制 [0-9a-zA-Z],61个字符,最大表示62进制
int convertToDec(char c)
{
int decNum;
if(c>='0' && c<='9')
decNum=c-48;
else if(c>='a' && c<='z')
decNum=c-87;
else if(c>='A' && c<='Z')
decNum=c-29;

return decNum;
}

//将十进制转换为这些字符 [0-9a-zA-Z],61个字符,最大表示62进制
char convertFromDec(int c)
{
char objchar;
if(c>=0 && c<=9)
objchar=c+48;
else if(c>=10 && c<=35)
objchar=c+87;
else if(c>=36 && c<=61)
objchar=c+29;

return objchar;
}

//从原进制转换为2~62的任意进制
string convert(int src,int obj,string num_str)
{
//    string num_str=to_string(num);
long long decNum=0;//十进制数(中间数)
for(int i=0;i<(int)num_str.size();++i)
decNum+=convertToDec(num_str[i])*pow(src,num_str.size()-1-i);

string strTmp;
long long tmp;
while(decNum>0)
{
tmp=decNum % obj;
strTmp=convertFromDec(tmp)+strTmp;
decNum/=obj;
}
return strTmp;
}

//合法性检查,M为源进制
bool IsVaild(const string& src_num,int M)
{
if(M>=2 && M<=10)//2-10进制
{
for(int i=0;i<(int)src_num.length();++i)
{
if(src_num[i]<'0' || src_num[i]-'0'>=M)
{
return false;
}
}
}
else if(M>=11 && M<=36)
{
for(int i=0;i<(int)src_num.length();++i)
{
if(!((src_num[i]>='0' && src_num[i]-'0'<M)
||  (src_num[i]>='a' && src_num[i]-'a'<M)))
{
return false;
}
}
}
else if(M>=37 && M<=62)
{
for(int i=0;i<(int)src_num.length();++i)
{
if(!((src_num[i]>='0' && src_num[i]-'0'<M)
||  (src_num[i]>='a' && src_num[i]-'a'<M)
||(src_num[i]>='A' && src_num[i]-'A'<M)))
{
return false;
}
}
}
return true;
}

//M进制转换为N进制,数字以string形式给出,需包含合法性检查
int main()
{
int M,N;//M进制转换为N进制
string src_num;//M进制的数
while(cin>>M>>N>>src_num)
{
//如果不超过36进制,大小写无所谓,可统一转换为小写
//transform(src_num.begin(),src_num.end(),src_num.begin(),::tolower);
if(!IsVaild(src_num,M))
{
cout<<"数据不合法"<<endl;
continue;
}
string obj_num;//N进制的数
obj_num=convert(M,N,src_num);
cout<<obj_num<<endl;
}
return 0;
}


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

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

/*
本程序说明:

参考了http://blog.csdn.net/jaster_wisdom/article/details/52107785,并进行完善。
大数2~62进制转换,只限于整数(负数可以提前去掉负号再用本程序处理)

*/

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main(){
int src,obj;//源进制和目标进制
string X;//待转换大数,用字符串处理
while(cin>>X>>src>>obj)
{
int data[1010];  //保存M进制下的各个位数
int output[1010];  //保存N进制下的各个位数
memset(output,0,sizeof(output));
for(int i=0;i<X.length();i++){
if(X[i]>='0' && X[i]<='9')
data[i] = X[i] - '0';
else if(X[i]>='a' && X[i]<='z')
data[i] = X[i] - 'a' + 10;
else if(X[i]>='A' && X[i]<='Z')
data[i] = X[i] - 'A' + 36;

}
int sum = 1;
int d  = 0;
int len = X.length();
int k = 0;
while(sum){
sum = 0;
for(int i=0;i<len;i++){
d = data[i] / obj;
sum += d;
if(i == len-1){
output[k++] = data[i] % obj;
}
else{
data[i+1] += (data[i] % obj) * src;
}
data[i] = d;
}
}
if(k == 0){
output[k] = 0;
k--;
}
if(k == -1){
cout<<0<<endl;
}
else{
for(int i=0;i<k;i++){
if(output[k-i-1] <=9)
cout<<output[k-i-1];
else if(output[k-i-1] <=35)
cout<<(char)(output[k-i-1]+ 'a' - 10);
else if(output[k-i-1] <=61)
cout<<(char)(output[k-i-1]+ 'A' - 36);
}
}
cout<<endl;
}
return 0;
}


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



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: