手撕大厂笔试之一文让你秒杀进制转化类问题

目录

个人介绍

前言

十进制转化为多进制

原理

代码模板

多进制转化为十进制

本质

代码模板

例题

   分析

   代码

负进制的转化

前言

原理

例题

   代码

 


个人介绍

各位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]];
}

例题

P1143 进制转换 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析

 (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。正确性的证明如下

例题

P1017 [NOIP2000 提高组] 进制转换 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

代码

#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);
	
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值