数制转换
描述
求任意两个不同进制非负整数的转换(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
解题思路
很明显,我们很难想到如何直接将两个数进行进制转换,故而,我们先将N进制数转换为十进制再行转换。在离散数学一书中提到一个算法:
对于N进制数,我们设为 a1a2a3…an
那么,转换为十进制就是
((((a1 * N + a2) * N) + a3) * N + …) * N) + an
所以推导出程序
for i -> len(s); do
ten = ten * N + preProcessChar(s[i])
endfor
其中,N代表进制,preProcessChar将字符转换为数字,如将‘A’转为10
当我们需要再次转换进制时,将公式逆推导,得出
i = 0
while (ten > 0)
r[i] = ten % N
ten /= N
i = i + 1
endwhile
reverse(r);
其中,N代表进制,r是目标字符串
上述代码只作为思路呈现,非任何语言
整体思路理清,那么,直接上代码
/*
* Author: Jeefy Fu
* Email: jeefy163@163.com
* Description:
* Origin URL: http://noi.openjudge.cn/ch0113/01/
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
int preProcessChar(char x) {
if ('a' <= x && x <= 'z')
return x - 'a' + 10;
if ('0' <= x && x <= '9')
return x - '0';
if ('A' <= x && x <= 'Z')
return x - 'A' + 10;
}
char preProcessNum(char x) {
if (0 <= x && x < 10)
return x + '0';
else
return x + 'A' - 10;
}
int main() {
int a, b;
char n[80] = {0};
scanf("%d%s%d", &a, n, &b);
long ten = 0;
for (int i = 0; i < strlen(n); i++) {
ten = ten * a + preProcessChar(n[i]);
}
// printf("%ld\n", ten);
char r[80] = {0};
int i = 0;
do {
r[i++] = ten % b;
ten /= b;
} while (ten > 0);
for (i = i - 1; i >= 0; i--) {
printf("%c", preProcessNum(r[i]));
// printf("%d\n", r[i]);
}
printf("\n");
}