正整数的任意进制转换
题目描述
将 p 进制 n 转换为 q 进制。p 和 q 的取值范围为【2,36】,其中,用到的数码按从小到大依次为:0,1,2,3,4,5,6,7,8,9,A,B,…,Z,不考虑小写字母。
注意:n 的长度不超过50位。
三个数之间用逗号间隔。
关于输入
1+m 行,
第1行为 m,表示后面有 m 行,m不小于1.
其后的m行中,每行3个数: 进制p,p进制数n,以及进制 q。
三个数之间用逗号间隔
关于输出
转换后的 q 进制数。
例子输入
6
18,2345678A123,18
15,23456,18
12,2345678,20
16,12345678,23
25,3456AB,21
18,AB1234567,22
例子输出
2345678A123
114E0
22B7A4
21A976L
7C2136
22JF0G367
解题分析
算法步骤
- 读取输入
程序首先读取一个整数 m,表示将要处理的数字组数。
接下来,对于每组数字,程序读取三个值:
p:当前的进制。
n:表示在 p 进制下的数(以字符串形式给出)。
q:目标进制。
2. 字符串转数字
将 p 进制的字符串 n 转换为数字。
对于字符串中的每个字符,根据其表示的数值进行转换。例如,‘A’ 转换为 10,‘3’ 转换为 3。
考虑到进制可能大于 10,因此字母字符(A-Z)也将被转换为相应的数字(10-35)。
3. 进制转换
使用“除 q 取余法”进行进制转换。
从 n 的最高位开始,逐位处理数字。
对于每一位,将其与前一位的余数相加,然后乘以 p,再除以 q。
每次除法操作后,余数保存下来,并将商作为该位在 q 进制下的值。
继续处理直到所有位都完成转换。
4. 输出结果
由于转换过程是从高位向低位进行的,因此最后得到的数字序列是反序的。
在输出前,需要将数字序列反转,以获得正确的 q 进制数。
例子说明
以输入 “16,12345678,23” 为例,程序将执行以下步骤:
读取输入:16(当前进制),“12345678”(16进制数),23(目标进制)。
字符串转数字:“12345678” 在 16 进制下表示的数值会被转换为数字形式。
进制转换:使用除 23 取余法,从 “12345678” 的最高位开始,逐步转换为 23 进制数。
输出结果:得到的 23 进制数是反序的,需要反转后输出。
通过这种方法,程序能够高效且准确地将任何给定的 p 进制数转换为 q 进制数。
代码实现
#include <stdio.h>char map[36]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int p,q;
char n[55];
int a[55],b[1000];int main(void) { int m; scanf("%d",&m);getchar();while(m--){scanf("%d",&p);getchar();int index=0; char ch;while((ch=getchar())!=','){n[index++]=ch;}n[index]='\0';scanf("%d",&q);//printf("%d,%s,%d\n",p,n,q);int len=strlen(n);for(int i=0;i<len;i++){a[i]=n[i]>='A'? (n[i]-'A'+10):n[i]-'0';}int lenb=0,flag=0;while(1){int res=0,temp=0;for(int i=0;i<len;i++){res=(a[i]+temp*p)%q;a[i]=(a[i]+temp*p)/q;temp=res;}b[lenb++]=res;for(int i=0;i<len;i++){if(a[i]){flag=0;break;}flag=1;}if(flag) break;}for(int i=lenb-1;i>=0;i--){printf("%c",map[b[i]]);}printf("\n");}return 0;
}