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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏blackheart的专栏

[C#6] 1-using static

0. 目录 C#6 新增特性目录 1. 老版本的代码 1 using System; 2 3 namespace csharp6 4 { 5 ...

20610
来自专栏小樱的经验随笔

codeforces 767A Snacktower(模拟)

A. Snacktower time limit per test:2 seconds memory limit per test:256 megabytes ...

3317
来自专栏大内老A

WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)

在.NET中,所有的集合都实现了IEnumerable接口,比如Array、Hashtable、ArrayList、Stack、Queue等。有的集合要求元素具...

2766
来自专栏恰同学骚年

.NET基础拾遗(3)字符串、集合和流

  众所周知,在.NET中String是引用类型,具有不可变性,当一个String对象被修改、插入、连接、截断时,新的String对象就将被分配,这会直接影响到...

961
来自专栏王磊的博客

宽字符编码和解码通用类[CodeWidthChartUtility]

  在做jsonp传递的时候遇到一个问题,当有特殊字符或中文的时候就会导致数据错误或者是乱码,刚开始有js的编码和解码和正则,都比较麻烦,现在找到了一种合适的解...

3098
来自专栏分布式系统和大数据处理

基于业务对象(列表)的排序

在上一篇文章 基于业务对象的筛选 中,我们讨论了如何实现Predicate<T>(T object)委托,自定义DateFilter 类来对业务对象进行筛选。与...

992
来自专栏大内老A

WCF技术剖析之十三:序列化过程中的已知类型(Known Type)

DataContractSerializer承载着所有数据契约对象的序列化和反序列化操作。在上面一篇文章(《数据契约(Data Contract)和数据契约序列...

26710
来自专栏互联网开发者交流社区

HashTable vs HashMap(三)

953
来自专栏GreenLeaves

C# Encoding

之前做公司项目的时候,对于C#编码这块总是一知半解,所以打算通过这篇笔记对C#编码(Encoding)进行彻底的扫盲,关于编码和字符集的基础知识,请参考字符集和...

2647
来自专栏跟着阿笨一起玩NET

C# 基础知识 protected 关键字

需要注意:实例不能访问指的是其他类中。如果是在父类或者子类中的实例当然是可以访问的。

1191

扫码关注云+社区

领取腾讯云代金券