题目1080:进制转换
时间限制:1 秒内存限制:32 兆特殊判题:否提交:6851解决:1762
题目描述:
将M进制的数X转换为N进制的数输出。
输入:
输入的第一行包括两个整数:M和N(2<=M,N<=36)。
下面的一行输入一个数X,X是M进制的数,现在要求你将M进制的数X转换成N进制的数输出。
输出:
输出X的N进制表示的数。
样例输入:
16 10
F
样例输出:
15
提示:
输入时字母部分为大写,输出时为小写,并且有大数据。
题目分析:
输入有大数据,所有采用大整数类型存储数据。
进制转换按照先转换为10进制的数,然后再转换到其他进制。
代码:
#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <queue>
#include <map>
#include <stdio.h>
#define MAX 100001
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct BigInteger{
int digit[MAX]; //数字低位放在digit数组的低位
int size;
void inint(){
size=0;
memset(digit,0,MAX);
}
void setBigInteger(char *s){ //10进制表示的数初始化大整数
inint();
int length=strlen(s);
int j=0;
int tmp=0;
int c=1;
for(int i=length-1;i>=0;i--){
tmp+=(s[i]-'0')*c;
j++;
c*=10;
if(j == 4 || i == 0){
digit[size++]=tmp;
j=0;
c=1;
tmp=0;
}
}
}
void setBigInteger(int a){ //用一个小整数初始化一个大整数
while(a!=0){
digit[size++]=a%10000;
a/=10000;
}
}
void outPut(){
//输出要从高位开始
for(int i=size-1;i>=0;i--){
if(i != size-1){
printf("%04d",digit[i]); //低位输出时不足4位要补0
} else{
printf("%d",digit[i]);
}
}
}
//大整数加法
BigInteger operator +(const BigInteger &b)const{
//大整数加法 从低位开始加
BigInteger ans;
ans.inint();
int carry=0; //进位
for(int i=0;i<b.size || i<size;i++){
//1.每个单元相加
int tmp=digit[i]+b.digit[i]+carry;
//2.计算进位
carry=tmp/10000;
//3.截取低四位并保存
ans.digit[ans.size++]=tmp%10000;
}
if(carry != 0){ //若计算后最高位任然有进位
ans.digit[ans.size++]=carry;
}
return ans;
}
BigInteger operator*(const int &k)const{
//大整数乘以k
BigInteger ans;
ans.inint();
int carry=0; //进位
for(int i=0;i<size;i++){
int tmp=digit[i]*k+carry;
ans.digit[ans.size++]=tmp%10000;
carry=tmp/10000;
}
while(carry != 0){
ans.digit[ans.size++]=carry%10000;
carry=carry/10000;
}
return ans;
}
BigInteger operator/(const int &k)const{
BigInteger ans;
ans.inint();
int remainder=0; //余数
for(int i=size-1;i>=0;i--){
//从大整数高位开始
int t=(remainder*10000+digit[i])/k;
remainder=(remainder*10000+digit[i])%k;
ans.digit[i]=t;//记录这一位的结果,当前除得的结果就应该放在相应的位置上
}
//确定ans的长度
for(int i=size-1;i>=0;i--) {
if(ans.digit[i] != 0){ //寻找最高位不为0的位置,即为ans的长度
ans.size=i;
break;
}
}
ans.size++;
return ans;
}
int operator%(const int &k)const{
//大整数对一个小整数求余
int remainder=0; //余数
for(int i=size-1;i >= 0;i--){
//从大整数的高位开始求余
remainder=(digit[i]+remainder*10000)%k;
}
return remainder;
}
};
int getValue(char c){
int ans=0;
if(c>='0' && c<='9'){
ans=c-'0';
}else{
ans=c-'A'+10;
}
return ans;
}
char setValue(int t){
char ans;
if(t>=0 && t<=9){
ans=t+'0';
}else{
ans=t+'A';
}
return ans;
}
BigInteger parseTo10(char *num,int m){
BigInteger ans;
ans.inint(); //ans初始化为0
int length=strlen(num);
BigInteger c;
c.setBigInteger(1); //权重 权重可能很大因此用大整数类型
for(int i=0;i<length;i++){ //累加值
int tmp=getValue(num[i]);
ans=ans+c*tmp; //大整数加法 、大整数和小整数的乘法
c=c*m;
}
return ans ;
}
char ans[MAX];
void parseToN(BigInteger t,int n,char *ans,int &size){
int length=0;
do{
int tmp=t%n;
//cout<<tmp<<endl;
char c=setValue(tmp);
ans[size++]=c;
t=t/n;
//t.outPut();
}while(t.digit[0]!=0 || t.size != 1);
return;
}
int main(int argc, char *argv[]) {
//测试
//BigInteger a,b;
//char c1[111],c2[222];
//cin>>c1>>c2;
//a.setBigInteger(c1);
//b.setBigInteger(c2);
// BigInteger c=a+b;
//c.outPut();
//1.读入数据
int m,n;
cin>>m>>n;
char num[MAX];
cin>>num;
//2.m进制num转换为10进制t
BigInteger t=parseTo10(num,m);
//t.outPut();
//3.10进制t转换为n进制ans
char ans[MAX]={0};
int size=0;
parseToN(t,10,ans,size);
//4.输出结果
for(int i=size-1;i>=0;i--){
cout<<ans[i];
}
return 0;
}
代码分析:
进制转换过程中涉及到大整数求和、大整数除小整数、大整数乘小整数、大整数对小整数求余等等;
写好大整数这些运算后基本上按照正常的进制转换思路就可以了。
(写好时九度正处于瘫痪中,系统不能正常判断程序是否AC)