H10:数制转换(选作)

“我来问道无馀说,云在青天水在瓶”

今天来看 数制转换!

题目描述

背景:我们通常使用的都是十进制的数字,但其实在生活中也经常会使用其它进制。

这个题目会给你两个不同的数字,它们不属于同一进制,要求你计算出当它们分别处于何种进制之中时,两个数字相等。譬如 12 和 5 ,在十进制下它们是不等的,但若 12 使用 3 进制而 5 使用六进制或十进制时,它们的值就是相等的。因此只要选择合适的进制, 12 和 5 就可以是相等的。

输入:程序的输入是两个数字 M 和 N( 其十进制的值不超过 1000000000) ,它们的进制在 2~36 之间。对于十以下的数字,用 0~9 表示,而十以上的数字,则使用大写的 A~Z 表示。

输出:求出分别在 2~36 哪种进制下 M 和 N 相等。若相等则输出相应的进制,若不等则输出错误信息。当然了,对于多种可能成立的情况,找出符合要求的进制最小的一组就行了。信息的格式见测试用例。

解题思路

本题的难点主要在三个方面:

一是由于输入中既有数字也有字符,那么该如何确定输入的变量类型?

二是已经完成输入,那么怎么把输入的量在新的数制下进行比较?

三是在新数制下两数相等后,如何找出“符合要求的进制最小的一组”?

关键参数

char str1[200],str2[200]:存储输入的字符串。

int num1[200],num2[200]:用于将输入的字符串逐字符转化成相应的数字,‘0’——‘9’变成0——9,‘A’——‘Z’变为10——35。

int new_num1,new_num2:将输入在新数制下转化为十进制比较。

难点分析

1、确定输入变量

针对第一点,我们采用字符串类型进行输入,再将每个字符转化为对应的数字。

int transform(char ch)
{
    if(ch>='0'&&ch<='9')
    {
        return (int)(ch-'0');
    }
    else if(ch>='A'&&ch<='Z')
    {
        return (int)(ch-'A'+10);
    }
}

2、在新数制下进行十进制比较

有点拗口,打个比方,比较二进制下的10和三进制下的10的大小,实际上就是在比较十进制下2和3的大小,结果也就显而易见了。

for(m=0;m<strlen(str1);m++)
            {
                num1[m]=transform(str1[m]);
            }
            for(n=0;n<strlen(str2);n++)
            { 
                num2[n]=transform(str2[n]);
            }

            for(m=0,new_num1=0;m<strlen(str1);m++)
            {
                new_num1=new_num1+num1[m]*pow(i,strlen(str1)-m-1);
            }
            for(n=0,new_num2=0;n<strlen(str2);n++)
            {
                new_num2=new_num2+num2[n]*pow(j,strlen(str2)-n-1);
            }
            if(new_num1==new_num2)
            {
                printf("%s (base %d) = %s (base %d)\n",str1,i,str2,j);
                flag=1;
                break;
            }

3、找出进制最小的一组

请各位试想一下,假如一组数是2 3 1 4,那么这组数还可能是二进制下的吗?当然不可能。这组数最少得是五进制下的数,就如同十进制下最多会出现0——9这几个元素。

故在程序循环比较时,我们可以从单个字符对应数的最大数加一开始循环,这也就是找到了循环开始的位置。

int start(char ch[]) {  //找最小合法进制转化数:比最大的一个元素大1
	int max = ch[0];
	for (int i = 0; i <= strlen(ch) - 1; i++) 
    {
		if (max < ch[i]) 
        {
			max = ch[i];
		}
	}
	if (max > 60)
    {
        max -= 'A';
        max += 10;
    }
		
    else
	    max -= '0';
 
	max += 1;
	return max;
}

完整代码

#include<stdio.h>
#include<string.h>
#include<math.h>

int transform(char ch)
{
    if(ch>='0'&&ch<='9')
    {
        return (int)(ch-'0');
    }
    else if(ch>='A'&&ch<='Z')
    {
        return (int)(ch-'A'+10);
    }
}

int start(char ch[]) {  //找最小合法进制转化数:比最大的一个元素大1
	int max = ch[0];
	for (int i = 0; i <= strlen(ch) - 1; i++) 
    {
		if (max < ch[i]) 
        {
			max = ch[i];
		}
	}
	if (max > 60)
    {
        max -= 'A';
        max += 10;
    }
		
    else
	    max -= '0';
 
	max += 1;
	return max;
}


int main()
{
    char str1[200],str2[200];
    int num1[200],num2[200];
    int i,j,temp,new_num1,new_num2,flag=0,m,n;

    scanf("%s %s",str1,str2);
    for(i=start(str1);i<=36;i++)
    {
        for(j=start(str2);j<=36;j++)
        {
            for(m=0;m<strlen(str1);m++)
            {
                num1[m]=transform(str1[m]);
            }
            for(n=0;n<strlen(str2);n++)
            { 
                num2[n]=transform(str2[n]);
            }

            for(m=0,new_num1=0;m<strlen(str1);m++)
            {
                new_num1=new_num1+num1[m]*pow(i,strlen(str1)-m-1);
            }
            for(n=0,new_num2=0;n<strlen(str2);n++)
            {
                new_num2=new_num2+num2[n]*pow(j,strlen(str2)-n-1);
            }
            if(new_num1==new_num2)
            {
                printf("%s (base %d) = %s (base %d)\n",str1,i,str2,j);
                flag=1;
                break;
            }
        }
    }
    if(flag==0)
        printf("%s is not equal to %s in any base 2..36",str1,str2);

    return 0;
}

以上就是本次分享的全部内容啦,小橘也还在学习中,水平有限,如有考虑不周之处烦请各位不吝赐教:)

如果各位客官觉得小橘写得还算用心,可以动动发财的小手点赞关注,大家的支持也是我更新的动力,在此谢过各位嘿嘿:>

  • 20
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值