题目描述:
求任意两个不同进制非负整数的转换(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进制作为转换的桥梁,所以任意进制的转换就可以变换为两步:
-
A进制转换为10进制: 从低位到高位(即从右往左)计算,第0位的权值是A的0次方,第1位的权值是A的1次方,第2位的权值A的2次方,依次递增下去,把最后的结果相加的值就是十进制的值。
-
10进制转为B进制:除B取余法,即每次将整数部分除B,余数为该位权上的数,而商继续除B,余数又为上一个位权上的数,这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数起,一直到最前面的一个余数。图例如下:
(注:另外一种做法就是十进制 -> 二进制 -> 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的源码解析。