【模拟】P1143进制转换

题目相关

题目描述

请你编一程序实现两种不同进制之间的数据转换。

输入格式

共三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A-F表示数码10-15,并且该n进制数对应的十进制的值不超过1000000000,第三行也是一个正整数,表示转换之后的数的进制m(2≤m≤16)。

输出格式

一个正整数,表示转换之后的m进制数。

输入输出样例

输入

16

FF

2

输出

11111111

分析

阅读完题目之后可以发现,其实就是求解一个N进制的数字如何转成M进制的数字。那么我们就思考下应该如何进行处理。我们可以通过10进行进行中转。先将N进制转成10进制,再将10进制转成M进制。

N进制转成10进制

首先,N进制如何转换成10进制。一般来说都是按权相加。将N进制从右向左进行扫描,将每一位数拿下并与N的次方值进行相乘,次方数从零开始,从右向左,逐渐加一。权值总和就是求出的10进制值。我们以二进制数0110为例,看如何求解出10进制内容。

次方数 3 2 1 0
二进制 0 1 1 0
权值 (0 imes 2^3) (1 imes 2^2) (1 imes 2^1) (0 imes 2^0)
0 4 2 0

总和就等于4+2=6

需要注意的是如何N进制大于10,就可能出现A ~ F的字符,分别对应10 ~ 15。那么N进制值可以使用字符串形式进行输入。在计算时在转成对应的整数即可。

int nToTen(int n,char num[]){
    int len=strlen(num);
    int ten=0;
    int cf=1;//N的次方值
    for(int i=len-1;i>=0;i--){//从右向左扫描
        if(num[i]>='0'&&num[i]<='9'){//'0'~'9'
            ten+=(num[i]-'0')*cf;//利用ASCII码值的连续性和差值进行转换
        }else{//'A'~'F'
            ten+=(num[i]-'A'+10)*cf;//利用ASCII码值的连续性和差值进行转换
        }
        cf*=N;//更新次方值
    }
    return ten;//返回十进制内容
}

10进制转成M进制

对于十进制转M进制,我们可以利用短除法进行处理。不断将数字除以M,保留余数,直到商的值为零,将余数倒着组合,形成的数字就是M进制的值。以十进制10转二进制为例:

[egin{array}{lr} &10 div 2 = 5 dots 0 \ &5 div 2 = 2 dots 1 \ &2 div 2 = 1 dots 0 \ &1 div 2 = 0 dots 1 end{array} ]

将余数倒着,从下往上组合,就是1010。

void tenToM(int ten,int m,char ans[]){
    char tmp[35]={0};//存储余数 
    int len=0;//余数个数 
    while(ten!=0){
        int u=ten%m;//分离余数 
        ten/=m;
        if(u>=0&&u<=9){//数字 0~9 转成 字符'0'~'9'
            tmp[len]=u+'0';
        }else{
            tmp[len]=u+'A'-10;//数字 10~15 转成 字符'A'~'F'
        }
        len++;
    }
    for(int i=0;i<len;i++){//倒着处理 
        ans[i]=tmp[len-1-i];
    }
}

两个步骤都理清了,那么两步合并一下就可以了。

代码实现

#include <iostream>
#include <cstring>
using namespace std;
int nToTen(int n,char num[]){
    int len=strlen(num);
    int ten=0;
    int cf=1;//N的次方值
    for(int i=len-1;i>=0;i--){//从右向左扫描
        if(num[i]>='0'&&num[i]<='9'){//'0'~'9'
            ten+=(num[i]-'0')*cf;//利用ASCII码值的连续性和差值进行转换
        }else{//'A'~'F'
            ten+=(num[i]-'A'+10)*cf;//利用ASCII码值的连续性和差值进行转换
        }
        cf*=n;//更新次方值
    }
    return ten;//返回十进制内容
}
void tenToM(int ten,int m,char ans[]){
    char tmp[35]={0};//存储余数 
    int len=0;//余数个数 
    while(ten!=0){
        int u=ten%m;//分离余数 
        ten/=m;
        if(u>=0&&u<=9){//数字 0~9 转成 字符'0'~'9'
            tmp[len]=u+'0';
        }else{
            tmp[len]=u+'A'-10;//数字 10~15 转成 字符'A'~'F'
        }
        len++;
    }
    for(int i=0;i<len;i++){//倒着处理 
        ans[i]=tmp[len-1-i];
    }
}
int main(){
	int N,M;
	char num[35]={0},ans[35]={0};
	cin>>N>>num>>M;
	int ten=nToTen(N,num);
	tenToM(ten,M,ans);
	cout<<ans; 
	return 0;
} 

题解视频

视频链接

不积硅步,无以至千里。
原文地址:https://www.cnblogs.com/wyloving/p/14062443.html