【模板小程序】非负数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; }
大数版本的解释(同转载至以上链接):
相关文章推荐
- 【模板小程序】十进制大数相加(正整数版本+整数版本【正负0】),包含合法性检查
- phpcms v9后台登陆模板修改方法和程序版本更新提示修改方法
- 【模板小程序】 十进制大数相乘(正数、负数、0均可),包含合法性检查
- 【模板小程序】十进制大数除法(输出商和余数)
- 九度OJ 教程62 大数处理之《进制转换》
- 一般处理程序读取模板文件
- 第5周作业-打字成绩判断程序(双版本)
- 给Delphi程序添加版本信息(EXE和Dll)
- QT 不同版本的编辑器 打包程序,保证其他电脑可用步骤
- 导入不同jq版本同同一段jq程序的影响
- vb.net 获取当前程序的版本(软件自己的版本)
- 轻量级持久层V2版本代码与模板
- Qt 程序异常结束 (MinGW 与 MSVC 版本切换)
- VC 程序Release版本的生成方法
- STM32串口采样与仪表步进电机控制程序(主程序与串口程序,需用正点原子定时器中断实验程序模板)
- 软件Release版本异常捕获程序(BugReport)
- 给Delphi程序(exe,dll)添加版本信息
- 用NuGet管理程序包时,如果解决方案目录下的packages文件夹中某一个程序包存在2个以上的版本,则会提示错误
- C 版本聊天室 C/S架构——客户端程序
- linux 程序在高版本编译后到低版本运行报错:Floating point exception ,解决方法。