目录
个人介绍
各位CSDN的友友们,大家好,我是小熙,一个算法小透明,希望在CSDN的大舞台可以和大家一起取得进步(^_^)
个人现状:上个学期在学校的ACM小组学了一个学期的算法,但是世界很大,我的梦想很远,我希望在我年轻的时候可以走出国门,到世界的其他地方看一看,再加上我的算法功底可能真的不太足以支持我在ACM比赛上做出成绩。所以我选择逐渐淡出ACM小组,并把之前的知识整理成博客供大家分享。
学习算法的小方法:知道算法的基本原理——>知道代码实现——>总结出代码模板并熟练于心——>基本模板题——>变式思维题
前言
进制转化主要就是两种形式,一种是十进制转化为多进制,一种是多进制转化为十进制。一旦转化为多进制那么这个多进制数据就是以字符串的方式存储了。其中需要用到map这样的一一映射的容器。
十进制转化为多进制
原理
原理: 取余除基,逆序输出。“基”就是进制,比如说十进制转十六进制,那么基就是16。
比如以下的十进制无转化为二进制下的101。
本质: 数字转字符串
代码模板
char a[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//十进制转化为多进制 while(ans)//表示的是十进制的数据 { str[++top]=a[ans%m];//str数组表示转化后的多进制数 ans/=m;//除基 }
多进制转化为十进制
本质
字符串转化为数字的情况。
代码模板
char a[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//十进制转化为多进制 map<char,int>b; int ans=0//ans是要转化的十进制的数据 for(int i=1;i<=strlen(str);i++)//从1开始正序去遍历 { ans*=n;//n是进制数 ans+=b[str[i]]; }
例题
分析
(1)由于数学上对十六进制的表示包含了字符串,“0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F”对应十六进制里面的0到15,是一一对应的映射关系,所以用map<char,int>容器来存储。——用来应对多进制变为十进制的情况。
(2)还有要注意的是多进制虽然是逆序输出,但是多进制转化为十进制的时候是正序遍历
代码
#include<bits/stdc++.h> using namespace std; char a[]="0123456789ABCDEF";//十六进制字符串 map<char,int>b; char str1[100];//表示的是多进制数据 char str2[100];//表示新转化的十六进制 int main() { for(int i=0;i<16;i++) b[a[i]]=i; int n; cin>>n; cin>>str1+1; int len=strlen(str1+1); int temp=1; long long ans=0; for(int i=1;i<=len;i++)//多进制转十进制的时候从一开始 { ans*=n; ans+=b[str1[i]]; } int cnt=0; int k; cin>>k; while(ans) { str2[++cnt]=a[ans%k];//取余 ans/=k;//除基 } for(int i=cnt;i>=1;i--) cout<<str2[i];//逆序输出 return 0; }
负进制的转化
前言
是不是从小到大我们所知道的只有正进制,而没有听说过负4进制,负16进制这种负的进制,来,下面我们就来介绍一波。
原理
(1)与之前正进制的转化相同,遵循取余除基的原则。
(2)取余中的余数是进制转化以后的数据。但是要求不为负,但是一旦进制为负数的时候取余就有可能为负数。所以一旦取余是负数,就将取余加上除数,除基的结果加上1。正确性的证明如下
例题
代码
#include<bits/stdc++.h> using namespace std; const int N=100; char a[]="0123456789ABCDEFGHIJKLMN"; char str[N]; int main() { int n,m; cin>>n>>m;int a1=n; int top=0; while(n) { int t=n%m; if(t>=0) { str[++top]=a[t]; n/=m; } else { t-=m; str[++top]=a[t]; n=n/m+1; } } cout<<a1<<"="; for(int i=top;i>=1;i--) cout<<str[i]; printf("(base%d)",m); }