九度OJ 题目1080:进制转换

题目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)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值