算法知识温习与夯实(高精度进制转换)

PKU1220
有t组cases。每组给你一个from,to,和串s。将from进制下的串s转化为to进制下的串
这个是个进制转化的问题,如果丢给我,我肯定会用传说中的转10再回转的方。但是对于大数据的话,肯定是过不了的,并且时间复杂度要高很多。

于是就有了下面的方法。

对大数的进制转换,可以不用大数的除法运算。
假设要把一个二进制数1011,转换成一个三进制数。
1、用二进制数的第一位1去除以3,商为0,余数是1
2、由于前面一位的除法结果有余数,所以要把余数*(进制)+该为数字。对于本例,就是1(余数)*2(进制)+0(当前这位的数值)=2。除以3后,商0,余数是2
3、同2所述,2(余数)*2(进制)+1(当前这位的数值)=5。5除以3后,商1,余数2
4、同2所述,2(余数)*2(进制)+1(当前这位的数值)=5。5除以3后,商1,余数2
以上四步可以表示为 1011(2-based) / 3(要转换成的基数) = 0011(2-based 商).. 2(3-based 余数)
然后再让0011除以3,重复以上步骤,直到商为0。每次的余数的逆序就是以3为基的数。

 

1011/3 -->0011 ..2
0011/3 -->0001 ..0
0001/3 -->0000 ..1

所以,1011(2-based) --> 102(3-based)

代码:
#include<iostream>
#include<string>
using namespace std;

string idx="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int getValue(char ch)//将字符c转换为相对应的数字
{
    if(ch>='0'&&ch<='9') return ch-'0';
    else if(ch>='A'&&ch<='Z') return ch-'A'+10;
    else return ch-'a'+36;
}
//将from进制下的字符串转换为to进制下的整数
string change(string s,int from,int to)
{
    string res="";
    int r,i,g,t,sum=1,len=s.size();
    while(sum!=0)    //sum作为循环结束标志
    {
        r=sum=0;
        for(i=0;i<len;i++)
        {
            t=getValue(s[i]);
            sum+=t;     //统计各位数字和
              g=t+from*r;
            s[i]=idx[g/to];  //存储该进制下的商
              r=g%to;  //除n取余
        }
        if(sum>0)
            res=idx.substr(r,1)+res; //先得到的余数放在低位
    }
    if(res=="")  //result为空串表明转换得到的结果为0
        res="0";
    return res;
}

int main(){
    string s;
    int i,t,from,to;
    cin>>t;
    while( t--){
        cin>>from>>to>>s;
        cout<<from<<" "<<s<<endl;
        cout<<to<<" "<<change(s,from,to)<<endl<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值