对于二进制的转换,我们通常有这样的公式,例如对于一个二进制111001,转换为十进制xx:
x=1×25+1×24+1×23+0×22+0×21+1×20x=1×25+1×24+1×23+0×22+0×21+1×20
事实上,对于任意R进制ABCDEF,转换为十进制xx,我们可以写成如下形式:
x=A×R5+B×R4+C×R3+D×R2+E×R1+F×R0x=A×R5+B×R4+C×R3+D×R2+E×R1+F×R0
那么反过来,对于一个十进制的xx,如果求得RR进制的数呢。
由上述公式,我们不难可以得出一个推导式:
F=x%RF=x%R
E=(x−F)/R%RE=(x−F)/R%R
依次倒退,直到求得A。
每次求一个字母(如F、E、D、C、B、A),都是减去取模的值,然后除以R,再对R取模。然后取得每个位置的字符拼成R进制值。
思路往往不难寻找,再复杂的问题,只要一点点抽丝剥茧,最后也会变得易于理解。
进制转换问题还有一个从M进制转换为N进制的问题,这个问题可以用10进制作为中间转换,也有一种称之为短除法的做法,本篇不深入讲解,后面再发一篇文章说明吧。
嗯,接着看题~
Problem Description
输入一个十进制数N,将它转换成R进制数输出。
Input
输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=16, R<>10)。
Output
为每个测试实例输出转换后的数,每个输出占一行。如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。
Sample Input
7 2
23 12
-4 3
Sample Output
111
1B
-11
源代码:GCC
#include <stdio.h>
//R是小于16的,如果大于16,修改这个表的大小
const char set[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int main()
{
int decimal, base, result[1007];
//输入十进制数字和需要转换的进制
while (scanf("%d %d", &decimal, &base) != EOF) {
//处理负数
if (decimal < 0) {
printf("-");
decimal = -decimal;
}
int cnt = 0;
//进制转换
//例如:对于16进制3B2A
//转换成十进制为 A * 16^0 + 2 * 16^1 + B * 16^2 + 3 * 16^3 = 10997
while (decimal) {
//取余,获得进制位数
int tmp = decimal % base;
//减少一个阶乘
decimal /= base;
//存入数据
result[cnt++] = tmp;
}
//倒着输出,一直到0
for (int i = cnt - 1; i >= 0; i--)
printf("%c", set[result[i]]);
printf("\n");
}
return 0;
}