算法题——任意进制转换

题目描述:


求任意两个不同进制非负整数的转换(2进制~16进制),所给整数在long所能表达的范围之内。 不同进制的表示符号为(0,1,…,9,a,b,…,f)或者(0,1,…,9,A,B,…,F)。 输入 输入只有一行,包含三个整数a,n,b。a表示其后的n 是a进制整数,b表示欲将a进制整数n转换成b进制整数。a,b是十进制整数,2 =< a,b <= 16。 输出 可能有多组测试数据,对于每组数据,输出包含一行,该行有一个整数为转换后的b进制数。输出时字母符号全部用大写表示,即(0,1,…,9,A,B,…,F)。

输入: 15 Aab3 7
输出: 210306


解题思路:

关于各个进制之间的转换,参考文章: 二、八、十、十六进制的转换
A进制转为B进制,,主要的转换思路是将10进制作为转换的桥梁,所以任意进制的转换就可以变换为两步:
进制转换图

  1. A进制转换为10进制: 从低位到高位(即从右往左)计算,第0位的权值是A的0次方,第1位的权值是A的1次方,第2位的权值A的2次方,依次递增下去,把最后的结果相加的值就是十进制的值。

  2. 10进制转为B进制:除B取余法,即每次将整数部分除B,余数为该位权上的数,而商继续除B,余数又为上一个位权上的数,这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数起,一直到最前面的一个余数。图例如下:
    十进制转为8进制图例
    (注:另外一种做法就是十进制 -> 二进制 -> B进制,如下图:)
    通过二进制转换


C++代码:

一、A进制转为10进制

Note: 这里直接通过参数指定了A进制是什么,所以难度系数降低了。有些情况下会只给出字符串,不给出具体是几进制,这个时候就需要进行判断。16进制一般是以0x开头的。

/**
 * @param str the string need to be converted.
 * @param base base of the string.
 * @return the decimal.
 */
int toDecimal(string str, int base)
{
    // str = "1011", base = 2;
    // Postive number, for negative, do it later.
    int count = 1;// 2^0 = 1
    int result = 0;
    long int length = str.length();
    for (long int i = str.length() - 1; i < str.length(); i--) 
    {
	    if (str[i] >= 'A' && str[i] <= 'F')
	    {
	        // For hex, A -> 10, B -> 11, C -> 12, D -> 13, E -> 14, F -> 15.
	        result += (str[i] - 'A' + 10) * count;
	    }
	    else if (str[i] >= 'a' && str[i] <= 'f')
	    {
	        // For hex, A -> 10, B -> 11, C -> 12, D -> 13, E -> 14, F -> 15.
	        result += (str[i] - 'a' + 10) * count;
	    }
	    else
	    {
	        result += (str[i] - '0') * count;
	    }
	    count *= base;
    }
    return result;
}

二、10进制转为B进制

Note: 这里考虑的也是非负数的情况,B进制的值也是给出来了的。

string decimalToOthers(int number, int base)
{
    string result = "";
    int current = 0;
    while (number != 0)
    {
        current = number % base;
        if (base > 10 && current >= 10)
        {
            // number = 10, base = 16 -> 10 % 16 = 10;
            current = current - 10 + 'A';
        }
        else
        {
            current = current + '0';
        }
        number /= base;
        result += current;// Combine them together.
    }
    reverse(result.begin(), result.end()); // Reverse the result.
    return result;
}

三、综合代码

结合前两个代码,所以整个算法题的代码如下:

int main(int argc, const char * argv[]) {
    string testNum;
    int a;
    int b;
    while (cin >> a >> testNum >> b) {
        // a to decimal.
        int temp = toDecimal(testNum, a);
        // Test to b.
        cout << decimalToOthers(temp, b) << endl;
    }
    return 0;
}

总结:

算法题就是需要先拆分成小问题,然后一步步解决小问题,最终解决整个问题。这里反转字符串最终是调用了STL的reverse函数。当然STL也提供了一些快捷转换的方法,可以参考官方文档。具体实现可以看看STL的源码解析。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值