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


/*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行,多么漂亮!

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

猜你喜欢

转载自blog.csdn.net/qq_37729102/article/details/79406465