进制转换问题
理论部分:
1.十进制转换为其它进制
十进制转换为其它进制可以直接使用连除的思想
-
十进制转换为二进制:
十进制的每一位数字对
2
进行取余,直到该十进制的数字结果为0结束,并且倒序输出结果。对应程序:
vector<int> BF(int num){ // 将十进制转化为二进制 vector<int> temp; while(num){ temp.push_back(num % B); num /= B; } reverse(temp.begin(), temp.end()); return temp; }
-
十进制转换为八进制
十进制的每一位数字对
8
进行取余,直到该十进制的数字结果为0
结束,并且逆序输出结果。对应的程序:
vector<int> OF(int num){ // 将十进制转换为八进制 vector<int> temp; while(num){ temp.push_back(num % O); num /= O; } reverse(temp.begin(), temp.end()); return temp; }
-
十进制转换为十六进制
十进制的每一位数字对
16
进行取余,直到该十进制的数字结果为0
结束,并且倒序输出结果。特殊情况:
对应的程序:
vector<char> HF(int num){ // 由于十六进制包含有字母,因此需要使用一个字符数组的格式将其进行存储 // 将十进制转换为十六进制 vector<char> temp; char tep; while(num){ if(num % H > 9){ // 如果数值大于9需要进行特殊处理 int th = num % H - 10; tep = 'A' + th; temp.push_back(tep); }else{ tep = '0' + (num % H); temp.push_back(tep); } num /= H; } reverse(temp.begin(), temp.end()); return temp; }
2.其它进制转换为十进制
其它进制转换为十进制只需按照公式进行嵌套即可,具体公式为: W = a 1 × x 0 + a 2 × x 1 + a 3 × x 1 + ⋯ a n × x n − 1 W = a_1 \times x^0 + a_2 \times x^1 + a_3 \times x^1 + \cdots a_n \times x^{n - 1} W=a1×x0+a2×x1+a3×x1+⋯an×xn−1,其中 W W W表示最终转换为十进制的结果, a i a_i ai表示其它进制的每一位的值( a 1 a_1 a1表示第一位的值, a n a_n an表示最高位上的值),x表示进制(如二进制转换位十进制,那么 x = 2 x = 2 x=2,如果是八进制,那么 x = 8 x = 8 x=8,十六进制对应的是 x = 16 x = 16 x=16)。
-
二进制转换为十进制
从末尾开始向前进行遍历,每一位都带入到公式中,可以得到: W = a 1 × 2 0 + a 2 × 2 1 + a 3 × 2 2 + ⋯ a n × 2 n − 1 W = a_1 \times 2^0 + a_2 \times 2^1 + a_3 \times 2^2 + \cdots a_n \times 2^{n - 1} W=a1×20+a2×21+a3×22+⋯an×2n−1。
代码实现:
int BD(string num){ // 二进制转换为十进制 int ans = 0; int carry = 0; for(auto v: num){ int tem = (v - '0'); ans += tem * pow(2, carry); // 参数为x的y次方 carry++; } return ans; }
-
八进制转换为十进制
从末尾开始向前进行遍历,每一位都带入到公式中,可以得到: W = a 1 × 8 0 + a 2 × 8 1 + a 3 × 8 3 + ⋯ a n × 8 n − 1 W = a_1 \times 8^0 + a_2 \times 8^1 + a_3 \times 8^3 + \cdots a_n \times 8^{n - 1} W=a1×80+a2×81+a3×83+⋯an×8n−1。
代码实现:
int OD(string num){ // 八进制转换为十进制 int ans = 0; int carry = 0; for(auto v: num){ int tem = (v - '0'); ans += tem * pow(8, carry); // 参数为x的y次方 carry++; } return ans; }
-
十六进制转换为十进制
从末尾开始向前进行遍历,每一位都带入到公式中,可以得到: W = a 1 × 1 6 0 + a 2 × 1 6 1 + a 3 × 1 6 3 + ⋯ a n × 1 6 n − 1 W = a_1 \times 16^0 + a_2 \times 16^1 + a_3 \times 16^3 + \cdots a_n \times 16^{n - 1} W=a1×160+a2×161+a3×163+⋯an×16n−1。
代码实现:
int HD(string num){ // 十六进制转化为十进制 int ans = 0; int carry = 0; for(auto v: num){ // 进行字母判断 int tem = (v - '0'); if(tem >= 10){ tem = (v - 'A') + 10; } ans += tem * pow(16, carry); // 参数为x的y次方 carry++; } return ans; }
代码:
完整的程序:
#include<iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
/*====================================== 进制转换程序 ==================================*/
// 其它进制(二进制,十进制,十六进制)转换为十进制
class OtherToBase{
public:
void OMain(int n, string num){
int ans;
reverse(num.begin(), num.end()); // 首先对数进行倒序排列
if(n == 1){
ans = BD(num);
}else if(n == 2){
ans = OD(num);
}else{
ans = HD(num);
}
// 进行输出
cout<<"进行转换后的结果为:"<<ans<<endl;
return ;
}
private:
int BD(string num){
// 二进制转换为十进制
int ans = 0;
int carry = 0;
for(auto v: num){
int tem = (v - '0');
ans += tem * pow(2, carry); // 参数为x的y次方
carry++;
}
return ans;
}
int OD(string num){
// 八进制转换为十进制
int ans = 0;
int carry = 0;
for(auto v: num){
int tem = (v - '0');
ans += tem * pow(8, carry); // 参数为x的y次方
carry++;
}
return ans;
}
int HD(string num){
// 十六进制转化为十进制
int ans = 0;
int carry = 0;
for(auto v: num){
// 进行字母判断
int tem = (v - '0');
if(tem >= 10){
tem = (v - 'A') + 10;
}
ans += tem * pow(16, carry); // 参数为x的y次方
carry++;
}
return ans;
}
};
// 十进制转换为其它进制(二进制,八进制,十六进制)
class BaseToOther {
public:
const int D = 10;
const int B = 2;
const int O = 8;
const int H = 16;
void Bmain(int n, int num){
vector<int> ans;
vector<char> cns;
if(n == 1){
ans = BF(num);
}else if(n == 2){
ans = OF(num);
}else{
cns = HF(num);
}
printf("转化后的结果为:\n");
if(ans.size()){
Trverse(ans);
}else Trverse(cns);
cout<<endl;
return ;
}
// 进行打印输出
void Trverse(vector<int> ans){
for(auto v : ans) cout<<v<<' ';
return ;
}
// 方法重载
void Trverse(vector<char> ans){
for(auto v : ans) cout<<v<<' ';
return ;
}
private:
vector<int> BF(int num){
// 将十进制转化为二进制
vector<int> temp;
while(num){
temp.push_back(num % B);
num /= B;
}
reverse(temp.begin(), temp.end());
return temp;
}
vector<int> OF(int num){
// 将十进制转换为八进制
vector<int> temp;
while(num){
temp.push_back(num % O);
num /= O;
}
reverse(temp.begin(), temp.end());
return temp;
}
vector<char> HF(int num){
// 将十进制转换为十六进制
vector<char> temp;
char tep;
while(num){
if(num % H > 9){
int th = num % H - 10;
tep = 'A' + th;
temp.push_back(tep);
}else{
tep = '0' + (num % H);
temp.push_back(tep);
}
num /= H;
}
reverse(temp.begin(), temp.end());
return temp;
}
};
void solve(){
printf("请输入需要使用的程序: \t1.十进制转换为其他进制 \t2.其他进制转换为十进制\n");
int num;cin>>num;
if(num == 1){
BaseToOther BaseT = BaseToOther(); // 进行实例化
printf("请输入需要将十进制转换为(1. 二进制 2. 八进制 3. 十六进制)\n");
int nm;cin>>nm;
printf("请输入需要转换的数字:\n");
int te;cin>>te;
switch(nm){
case 1:{
// 转换为二进制
BaseT.Bmain(nm, te);
break;
}
case 2:{
// 转换为八进制
BaseT.Bmain(nm, te);
break;
}
case 3:{
// 转换为十六进制
BaseT.Bmain(nm, te);
break;
}
}
}else{
OtherToBase OtherT = OtherToBase();
printf("请输入需要将(1. 二进制 2. 八进制 3. 十六进制)转换为十进制\n");
int nm;cin>>nm;
cout<<"请输入要进行转换的数字:"<<endl;
string te; cin>>te;
switch(nm){
case 1:{
// 将二进制转换为十进制
OtherT.OMain(nm, te);
break;
}
case 2:{
// 将八进制转换为十进制
OtherT.OMain(nm, te);
break;
}
case 3:{
// 将十六进制转换为十进制
OtherT.OMain(nm, te);
break;
}
}
}
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout<<"欢迎使用进制转换程序!!!"<<endl<<endl;
int t = 1;
while(true){
if(!t) break;
solve();
cout<<"是否需要继续使用?(1. 继续使用 0. 退出程序)"<<endl;
cin>>t;
}
cout<<"程序结束欢迎下次使用!!!"<<endl;
return 0;
}
习题练习
题目:
思路:
本质上是将一个十进制数转换为26
进制数,然后映射到字母表中去,但并不是普通的映射,存在特例情况,如:在26
进制中的1 0
对应十进制是26
,因此1 0
对应的字母应该是Z
,在通常情况下,十进制中数字26
对应的字母是Z
但是在进制转换时,将26
转换为了10
,这就导致了映射的问题,我们需要处理每一个这样的问题,如果遇到某个位置上的值为0
,那么需要输出Z
,并且需要从更高的位上-1
(如果存在更高的位的话),并且在每次进行处理的时候对每一个位置上的值进行+26
,并于26
进行取余运算,将每一个位置得到的值存入到数组中,最后在逆序输出这个数组即可。
要注意:如果是字符数组,那么逆序输出的时候需要- 1
,因为字符数组的最后一个值默认是'\0'
。
代码:
// 年号字串
#include<bits/stdc++.h>
using namespace std;
void solve(){
int n;
cin>>n;
vector<string> ans;
vector<int> nums;
const int N = 26;
while(n){
nums.push_back( n % 26);
n /= N;
}
// 定义一个字符容器nuans,用于存放最后的结果
vector<char> nuans;
for(int i = 0;i < nums.size();i ++){ // 对每一位进行判断
nums[i] = (nums[i] + 26) % 26; // 首先对每一位进行 + 26 然后再与26进行取余,这样可以保证数据在正确的范围内
if(nums[i] == 0 && i + 1 < nums.size()){ // 处理每一个位置上为0的情况,如果该位置上为0,那么就从高位上减去1(如果高位存在的话)
nums[i + 1]--;
nuans.push_back('Z');
}else{
// 处理常规的情况
char ct = char('A' + nums[i] - 1);
nuans.push_back(ct);
}
}
for(int i = nuans.size() - 1;i >= 0;i--) cout<<nuans[i]; // 要注意这里需要进行-1,最后一个字符是空字符'\0'!!!!!!
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t = 1;
while(t--){
solve();
}
return 0;
}