欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

这道题其实我们都走错方向了?

程序员文章站 2022-07-15 09:35:46
...


/*C2-2 进制转换 (100 满分)

题目描述

 

已知一个只包含 0 1 的二进制数,长度不大于 10 ,将其转换为十进制并输出。

输入描述

 

输入一个二进制整数n,其长度大于0且不大于10

输出描述

 

输出转换后的十进制数, 占一行

样例输入

110

样例输出

6*/

包括本人在内,在思考此题时都走错了方向,卡在了计算二进制整数长度上。有人说,用字符一个个接收字符类型的整数再一个个转换为整数,顺便计数,还有人说利用异或等原理用循环将数的二进制反复向右移动,还有人说,用c++自带的库函数直接实现转换,还有人说......等等等等,直到本人在csdn上看到了一个算法,才恍然大悟,之前你们都走错方向了!其实这道题不就是将整数倒着输出的变式么?只不过多了模数2,还记得将整数倒着输出的算法吗?

#include<iostream>
using namespace std;
int main()
{/*Reverse digit */
    int m,n;
    cout<<"Please input:"<<endl;
    cin>>m;
    do{
    n=m%10;
    cout<<n;
    m/=10;
    }while(m);
    cout<<endl;
}

比如输入123,怎么办,是不是先对12310取余?,取出来的是什么?当前n的末位3,3取出来了,输出,再想输出2,怎么办?用除操作将123“砍掉”13,现在m=12n=3,下一循环,12去模10取余取到2n=2输出,再通过除操作“砍掉”末位2,重复上述过程,直到m=0,上述过程反复进行的就是模10取余取到最低位拿来用,取好了用除操作“砍掉”最低位继续。有人可能会说“我还是不明白这和二进制转十进制有什么关系”。别急,我们先来看看二进制是怎么转为十进制的吧!

假如给出整数0111,你是怎么转换的?是不是0x23+1x22+1x21+1x20次?那么不是就可以依次从最低位取到最高位,每取1位进行操作了吗?不过在此之前要注意下0111在计算机中就是111,前面的0忽略的。好了,我们来分析下具体过程。

首先将011110取最低位1,进行模数为2的操作,也就是用1去乘20次,再用除操作“砍掉”当前最低位的1,再模10取最低位,进行模数为2的操作,也就是用1去乘21次,再用除操作“砍掉”当前最低位1,如此循环,直到01110

模数为2的操作可以调用数学函数库,也可以用*=操作,都可以。下面是具体代码:

#include<iostream>
using namespace std;
int main()
{
    int n,r,m=1,sum=0;
    cin>>n;
    do{
    r=n%10;//取余
    sum+=r*m;//累加余数乘以模数m
    m*=2;//模数乘以2
    n/=10;//n除以10
    }while(n);
    cout<<sum;//输出累加和
    return 0;
}

第一次看到这些代码的时候,真是感叹之前的我太愚蠢了,绕了一大圈,结果还是将整数倒着输出那道简单题目的变式!!不过这代码确实相比精简多了,又易懂,你看核心算法才4行,多么漂亮!

这件事告诉我们,题目往往没我们想得那么复杂,要不断注意知识迁移,才能锻炼发散思维,提高分析能力,最终达到万变不离其宗!