算法学习记录:进制转换

目录

前言:

背景知识:

正文:

任意进制转十进制:

原理:

笔算:

机器算:

十进制转任意进制:

原理:

笔算:

机器算:

例题集:

蓝桥OJ 1555:进制

蓝桥OJ 2095:九进制转十进制

蓝桥OJ 1230:进制转换

总结:


前言:

  算法学习记录不是算法介绍,本文记录的是从零开始的学习过程(见到的例题,代码的理解……),所有内容按学习顺序更新,而且不保证正确,如有错误,请帮助指出。

学习工具:蓝桥OJ,LeetCode

背景知识:

0B 表示二进制的前缀 

0O表示八进制的前缀 

0x表示十六进制的前缀

正文:

任意进制转十进制:

原理:

一个K进制的数,

给它加1     == 给它个位上加1;

给它加 K    == 给它十位上加1;

给它加 K*K == 给它百位上加1;

以此类推,发现一个规律:它的值(十进制)等于它的每一位数乘以它的位权

位权就个数字,表示该单位的大小。

图解:

笔算:

举例: 

机器算:

模板:

//数组a以数字形式存每一位
long long x = 0;
for(int i = 1;i <= n; i++)
{
    x = x * k + a[i];
}
cout << x << endl;

十进制转任意进制:

原理:

任意一个十进制数都可以写成这样展开的形式:

笔算:

机器算:

long long x;
cin >> x;
while(x)a[++cnt] = x % k, x /= k;
reverse(a + 1, a + 1 + cnt);
//要翻转下数组,才能使得高位在正确位置

例题集:

蓝桥OJ 2489:进制

#include<iostream>

using namespace std;
const int N = 50;
int a[N];
int main()
{
	string s = "2021ABCD";
	for(int i = 0;i < s.length();i ++)
	{
		if('0' <= s[i] && s[i] <= '9')a[i + 1] = s[i] - '0';
		else a[i + 1] = s[i] - 'A' + 10;
	}
	
	long long x = 0;
	for(int i = 1;i <= s.length(); ++i)
	{
		x = x * 16 + a[i];
	}
    cout << x ;
	return 0;
}
//另解:
//unsigned int x = 0x2021abcd;
//cout << x << endl;

蓝桥OJ 2095:九进制转十进制

#include<iostream>
using namespace std;

const int N = 10;
int a[N];
int main()
{
	int n = 4;
	string s = "2022";
	for(int i = 1;i <= 4; ++i)a[i] = s[i - 1] - '0';

	long long x = 0;
	for(int i = 1;i <= n;i ++)x = x * 9 + a[i];
	cout << x << endl;
	return 0;
}

蓝桥OJ 1230:进制转换

#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1000;
int a[N];

char ch[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void solve()
{
	int n,m; cin >> n >> m;
	string s;cin >> s;
	int len = s.length();
	s = "#" + s;
for(int i = 0;i <= len; ++i)
{
	if('0' <= s[i] && s[i] <= '9')a[i] = s[i] - '0';
	else a[i] = s[i] - 'A' + 10;
}

ll x = 0;
for(int i =1;i <= len;++i)x = x * n + a[i];

string ans;
while(x){
	
  ans += ch[x % m];
  x /= m;
}
reverse(ans.begin(),ans.end());
cout << ans << '\n';
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _;cin >> _;
	while(_--){
		solve();
	}
	return 0;
}

总结:

类似泰勒展开:不易求解的函数展开成多项式的形式。

进制转换的本质就是将一个数字按照位权展开。(位权展开法)

根据这一规律,进制转换就是展开和展开的逆过程的重复。

记忆模板:

/*进制转换*/
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int n = 100;
int a[n];
int main()
{
/*转至十进制*/
ll x = 0;
int k;cin>> k;
for(int i = 1;i <= n; ++ i)
{
	
	x = x * k + a[i];
}
cout << x << '\n';

/*转出十进制*/
int cnt;
ll u;cin >> u;
while(u)a[++ cnt] = x % k,x/=k;
reverse(a+1,a+1+cnt);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值