一、题型分类
进制转换是考研机试必考题型,核心是数位拆解(取模 + 整除) 和数位合并(乘 + 加),主要分为以下 9 类:
- 反序数:如 123 → 321
- 10 进制转 2 进制:如 7 → 111
- 10 进制转 16 进制:如 10 → A
- 10 进制转 x 进制(通用)
- x 进制转 10 进制(通用)
- x 进制转 y 进制(拆解为:x→10→y)
- 字符串转浮点数:如 "31.25" → 31.25
- 浮点数转字符串:如 23.45 → "23.45"
- 字符串 / 整型互转:用
atoi/itoa函数
二、核心代码实现(纯 C 语言)
1. 反序数
cpp
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int ans = 0; // 存储反序结果
while (n > 0) { // 逐位拆解n
ans *= 10; // 结果左移一位
ans += (n % 10); // 取当前最后一位
n /= 10; // 去掉最后一位
}
printf("%d\n", ans);
return 0;
}
测试用例 :输入123 → 输出321
2. 10 进制转 x 进制(x<10)
cpp
#include <stdio.h>
int main() {
int n, x;
int s[105]; // 存储每一位结果
scanf("%d%d", &n, &x); // 输入10进制数n和目标进制x
int cnt = 0; // 数组下标(记录位数)
while (n > 0) { // 逐位拆解
int w = n % x;
s[cnt++] = w;
n /= x;
}
// 反序输出(拆解时是逆序存储)
for (int i = cnt - 1; i >= 0; i--) {
printf("%d", s[i]);
}
printf("\n");
return 0;
}
测试用例 :输入7 2 → 输出111
3. 10 进制转 x 进制(通用版,支持 x≥10)
cpp
#include <stdio.h>
int main() {
int n, x;
char s[105]; // 存储字符(10以上用A/F等表示)
scanf("%d%d", &n, &x);
int cnt = 0;
while (n > 0) {
int w = n % x;
if (w < 10) {
s[cnt++] = w + '0'; // 数字转字符(如5→'5')
} else {
s[cnt++] = (w - 10) + 'A'; // 10→A,11→B...(小写加'a')
}
n /= x;
}
// 反序输出
for (int i = cnt - 1; i >= 0; i--) {
printf("%c", s[i]);
}
printf("\n");
return 0;
}
测试用例 :输入10 16 → 输出A
4. x 进制转 10 进制(以 x=2 为例)
cpp
#include <stdio.h>
#include <string.h>
int main() {
char s[105];
scanf("%s", s); // 输入二进制字符串
int ans = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
ans *= 2;
if (s[i] == '1') {
ans += 1;
}
}
printf("%d\n", ans);
return 0;
}
测试用例 :输入111 → 输出7
5. x 进制转 10 进制(通用版)
cpp
#include <stdio.h>
#include <string.h>
int main() {
char s[105];
int x;
scanf("%s%d", s, &x); // 输入x进制字符串+进制数x
int ans = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
ans *= x; // 左移一位
if (s[i] >= '0' && s[i] <= '9') {
ans += (s[i] - '0'); // 数字字符转数值
} else {
ans += (s[i] - 'A') + 10; // 字母字符转数值(A→10)
}
}
printf("%d\n", ans);
return 0;
}
测试用例 :输入A 16 → 输出10
6. x 进制转 y 进制(通用版)
cpp
#include <stdio.h>
#include <string.h>
int main() {
char s[105];
int x, y;
// 输入x进制字符串 + 原进制x + 目标进制y
scanf("%s%d%d", s, &x, &y);
// 第一步:x进制转10进制
int ans = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
ans *= x;
if (s[i] >= '0' && s[i] <= '9') {
ans += (s[i] - '0');
} else {
ans += (s[i] - 'A') + 10;
}
}
// 第二步:10进制转y进制
char out[105];
int cnt = 0;
while (ans > 0) {
int w = ans % y;
if (w < 10) {
out[cnt++] = w + '0';
} else {
out[cnt++] = (w - 10) + 'A';
}
ans /= y;
}
// 反序输出
for (int i = cnt - 1; i >= 0; i--) {
printf("%c", out[i]);
}
printf("\n");
return 0;
}
测试用例 :输入A 16 2 → 输出1010
7. 大数进制转换(30 位 10 进制转 2 进制)
说明:普通整型无法存储 30 位十进制数,需用数组模拟大数运算
cpp
#include <stdio.h>
#include <string.h>
// 存储十进制大数的数组 + 二进制结果缓冲区
char s[40], buf[200];
int main() {
int num[40];
// 多组输入,直到EOF
while (scanf("%s", s) != EOF) {
int len = strlen(s);
// 字符串转整数数组(num[0]是最高位)
for (int i = 0; i < len; i++) {
num[i] = s[i] - '0';
}
int i = 0, len_str = 0;
// 大数除2取余法
while (i < len) {
// 取当前最后一位的余数(二进制位)
buf[len_str++] = num[len - 1] % 2 + '0';
// 大数除法:逐位除2,处理余数
int c = 0;
for (int j = i; j < len; j++) {
int tmp = num[j];
num[j] = (num[j] + c) / 2; // 高位先除2
if (tmp % 2 == 1) {
c = 10; // 奇数则余数为1,下一位加10
} else {
c = 0;
}
}
if (num[i] == 0) {
i++; // 高位为0则跳过,减少计算
}
}
// 反序输出二进制结果
for (int j = len_str - 1; j >= 0; j--) {
printf("%c", buf[j]);
}
printf("\n");
}
return 0;
}
题目信息:
- 描述:将长度≤30 位的十进制非负整数转二进制输出
- 输入样例:
0、1、3、8 - 输出样例:
0、1、11、1000 - 来源:DreamJudge 1178
三、核心知识点总结
- 进制转换核心逻辑:
- 10 进制转 x 进制:除 x 取余,逆序输出;
- x 进制转 10 进制:按位加权求和(每一位 ×x^ 位权);
- x 进制转 y 进制:先转 10 进制,再转 y 进制。
- 大数处理技巧:
- 用字符数组存储超大数,用整数数组模拟加减乘除;
- 大数除法需逐位处理,记录余数传递给下一位。
- 字符 / 数值转换:
- 数字字符转数值:
'5' - '0' = 5; - 数值转字符:
10 → 'A'(计算方式:10-10+'A')。
- 数字字符转数值: