有帮助就点个赞呗👍
1. 入门–简单十进制转二进制代码模板
记住9=1*2^0+0*2^1+0*2^2+1*2^3
#include<bits/stdc++.h>
using namespace std;
//俩行关键代码搞定进制转换问题
void dectobin(int n)
{
if(n==0)
return;
else
{
dectobin(n/2);
cout<<n%2;
}
}
int main()
{
int n;
while(cin>>n)
{
dectobin(n);
cout<<endl;
}
return 0;
}
2. 进阶–十进制进制转化任意进制
#include<bits/stdc++.h>
using namespace std;
char bits[]={"0123456789ABCDEF"};
void convto(char *s,int n,int b)
{
//边界判断
if(n==0)
return;
//开始递归
convto(s,n/b,b);
int len=strlen(s);
s[len]=bits[n%b];
s[len+1]='\0';
}
int main()
{
int n,b;
char s[99]="";
cin >> n;
cin >> b;
//n十进制数,b要转换的进制
convto(s, n, b);
cout << s << endl;
return 0;
}
3. 进阶–任意长度十进制转二进制
3.1 基础知识–高精度加减乘除
高精度的加减乘除就只是 模拟与平时类似的手算而已
以下模板默认规定:
为计算方便,均采用Vector存储数据,并且数值的低位存在数组的高位,即123存储为,a[0]=3,a[1]=2,a[2]=3
3.1.1. 高精度加法
思路:
从最低位开始加,每次相加前 把上一位的进位加进来,之后把结果存起来,并且更新进位
#include<iostream>
#include<vector>
using namespace std;
//为了防止每次调用都得重新开一个空间存vector,加个&引用一下
vector<int> add(vector<int> &a,vector<int> &b)
{
vector<int> c;
int t=0;
for(int i=0;i<a.size()||i<b.size();i++)
{
//不能非法越界
if(i<a.size()) t+=a[i];
if(i<b.size()) t+=b[i];
//每一位的运算结果
c.push_back(t%10);
//进位
t=t/10;
}
if(t==1) c.push_back(1);
return c;
}
int main()
{
vector<int> a,b;
string m,n;
cin>>m;
cin>>n;
for(int i=m.size()-1;i>=0;i--) a.push_back(m[i]-'0');
for(int i=n.size()-1;i>=0;i--) b.push_back(n[i]-'0');
auto c= add(a,b);
for(int i=c.size()-1;i>=0;i--)
cout<<c[i];
return 0;
}
3.1.2. 高精度减法
思路:
与加法一样,计算前得先判断比较长度,每次相减前,把上一位的借位先减去,之后把结果存起来,并且更新借位
#include<iostream>
#include<vector>
using namespace std;
//a>=b
bool cmp(vector<int> &a,vector<int> &b)
{
//先判断长度
if(a.size()!=b.size()) return a.size()>b.size();
//再从高位往地位判断大小
for(int i=a.size()-1;i>=0;i--)
if(a[i]!=b[i])
return a[i]>b[i];
//最后就是相等的情况
return 1;
}
vector<int> sub(vector<int> &a,vector<int> &b)
{
vector<int> c;
int i=0;//借位标志位
for(int j=0;j<a.size();j++)
{
//同步借位标志位
i=a[j]-i;
//相当于把b[i]加上,即i=a[i]-b[i]-i
if(b.size()>j) i-=b[j];
//a%b返回正数值,(a%b+b)%b
c.push_back((i%10+10)%10);
//更新标志位
if(i<0) i=1;
else i=0;
}
//去掉前导0
while(c.size()>1&&c.back()==0) c.pop_back();
return c;
}
int main()
{
string a,b;
vector<int> A,B;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
if(cmp(A,B))
{
auto c = sub(A,B);
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
}
else
{
auto c = sub(B,A);
cout<<'-';
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
}
//cout<<cmp(A,B);
return 0;
}
3.1.3. 高精度乘法
思路:
主要是以A(大数)为基准,b(小数)当作一个整体,A的每一位乘以b的每一位即可
#include<iostream>
#include<vector>
using namespace std;
vector<int> mul(vector<int> A,int b)
{
vector<int> C;
int t=0;
for(int i=0;i<A.size()||t!=0;i++)
{
//把A的几个位数都乘了 并且加上进位
if(i<A.size()) t+=A[i]*b;
C.push_back(t%10);
if(b==0) break;//去掉前导0
//进位
t/=10;
}
return C;
}
int main()
{
string a;
int b;
vector<int> A;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
auto C=mul(A,b);
for(int i=C.size()-1;i>=0;i--) cout<<C[i];
return 0;
}
3.1.4. 高精度除法
思路:
与平常除法一样,模拟手算,一位一位除就行了,注意得加上上一位的余数
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
// A/b=C...r A为大数,b为被除数,r为余数
vector<int> dec(vector<int> &A,int b,int &r)
{
vector<int> c;
//注意这个得从最低位开始除
for(int i=A.size()-1;i>=0;i--)
{
r=r*10+A[i];
c.push_back(r/b);
r=r%b;
}
reverse(c.begin(),c.end());
while(c.size()>1&&c.back()==0) c.pop_back();
return c;
}
int main()
{
string a;
vector<int> A;
int b;
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
int r=0;
auto c=dec(A,b,r);
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
cout<<endl<<r<<endl;
}
3.2 正式解题
题目链接:https://www.acwing.com/problem/content/description/3376/
递归将十进制转为二进制,配合一个高精度除法即可
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
// A/b=C...r A为大数,b为被除数,r为余数
vector<int> dec(vector<int> &A,int b,int &r)
{
vector<int> c;
//注意这个得从最低位开始除
for(int i=A.size()-1;i>=0;i--)
{
r=r*10+A[i];
c.push_back(r/b);
r=r%b;
}
reverse(c.begin(),c.end());
while(c.size()>1&&c.back()==0) c.pop_back();
return c;
}
void convert(vector<int> c)
{
if(c.size()==1&&c.back()==0)
return;
else
{
int r=0;
auto a=dec(c,2,r);
convert(a);
cout<<r;
}
}
int main()
{
string a;
while(cin>>a)
{
vector<int> A;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
int r=0;
if(A.size()==1&&A.back()==0)
{
cout<<0<<endl;
continue;
}
convert(A);
cout<<endl;
}
}
4. 进阶–任意长度十进制进制反转
题目链接:https://www.acwing.com/problem/content/description/3398/
利用前面所学知识,即可实现十进制反转
直接暴力十进制转二进制,之后再转为十进制即可
但是!输入的数据,有足足1000位,而int只能存下32位,因此得使用高精度的算法来求解
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> cnt;//用来存递归的数据
//高精度除法
// A/b=C...r A为大数,b为被除数,r为余数
vector<int> dec(vector<int> &A,int b,int &r)
{
vector<int> c;
//注意这个得从最低位开始除
for(int i=A.size()-1;i>=0;i--)
{
r=r*10+A[i];
c.push_back(r/b);
r=r%b;
}
reverse(c.begin(),c.end());
while(c.size()>1&&c.back()==0) c.pop_back();
return c;
}
//高精度加法
vector<int> add(vector<int> &a,vector<int> &b)
{
vector<int> c;
int t=0;
for(int i=0;i<a.size()||i<b.size();i++)
{
//不能非法越界
if(i<a.size()) t+=a[i];
if(i<b.size()) t+=b[i];
//每一位的运算结果
c.push_back(t%10);
//进位
t=t/10;
}
if(t==1) c.push_back(1);
return c;
}
//二进制转十进制,遍历
vector<int> convert_2to10(vector<int> a)
{
vector<int> sum;
vector<int> wight;
wight.push_back(1);
for(int i=0;i<a.size();i++)
{
if(a[i]==1)
sum=add(sum,wight);
wight=add(wight,wight);
}
return sum;
}
//十进制转二进制,递归
void convert_10to2(vector<int> c)
{
if(c.size()==1&&c.back()==0)
return;
else
{
int r=0;
auto a=dec(c,2,r);
convert_10to2(a);
cnt.push_back(r);
}
}
int main()
{
string a;
cin>>a;
vector<int> A;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
int r=0;
//特殊值0的判断
if(A.size()==1&&A.back()==0)
{
cout<<0<<endl;
return 0;
}
convert_10to2(A);
auto sum=convert_2to10(cnt);
for(int i=sum.size()-1;i>=0;i--) cout<<sum[i];
return 0;
}
难得写个笔记,点个赞再走呗~
肥肠感谢!
😁