2的n次幂

问题描述

任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001。
  将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0
  现在约定幂次用括号来表示,即a^b表示为a(b)
  此时,137可表示为:2(7)+2(3)+2(0)
  进一步:7=2^2+2+2^0 (2^1用2表示)
  3=2+2^0 
  所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)
  又如:1315=2^10+2^8+2^5+2+1
  所以1315最后可表示为:
  2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
输入格式
  正整数(1<=n<=20000)
输出格式
  符合约定的n的0,2表示(在表示中不能有空格)
样例输入
137
样例输出
2(2(2)+2+2(0))+2(2+2(0))+2(0)
样例输入
1315
样例输出
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)


思路

  简单点的话,老老实实算二进制,再输出;这里涉及到每位二进制的指数也要一起分解,即在分解我们的数的途中还要分解,明显的递归。

  但是也可以不用算出二进制,使用位运算直接对二进制进行操作,这里用 137 来演示,具体如下:

  首先我们知道 137 的二进制为:10001001

1、获取最高位二进制

1 for(e=0, now=1; now <= n; now<<=1, e++);

 

这里的 e 表示当前二进制的位置,也就是我们需要的指数,初始化为 0 位;now 表示 2 的 n 次方,用来与我们输入的数 n 相比较,判断具体要移动多少位。这里我们循环结束后应该是这样子的:

010001001  原数 137

100000000  2 的 8 次方 256

此时, e = 8, now = 256

2、判断当前位是否是 0 位

这是大概最精彩的部分

1 for(;now>0;now>>=1, e--){
2         if(now & n){
      // 继续
3   }

 

之前我们已经知道了 now 和 n 的二进制,接下来,当循环条件满足时,我们就不断将二进制左移(e--),同时将 now 与 n 按位与,得到如下结果:

010001001  原数 137

100000000  2 的 8 次方 256

000000000  0

判断条件为假,继续下一次循环:

010001001  原数 137

010000000  2 的 7 次方 128,因为我们右移了一位

010000000  此时不为0

判断条件为真,继续执行下面的内容,直到把当前的二进制读取完。

下一次循环结果为

010001001  原数 137

001000000  2 的 6 次方 64

000000000  此时为0

一直下去......

3、判断输出

 1 void fun(int n)
 2 {
 3     int now, e;
 4     for(e=0, now=1; now <= n; now<<=1, e++);
 5     cout<<"2";
 6     for(;now>0;now>>=1, e--){
 7         if(now&n){
 8             if(now > 2){      // now 大于2,说明指数大于2,还要继续分解
 9                 cout<<"(";
10                 fun(e);       // 递归
11                 cout<<")";
12             }
13             if(now == 2);      // 等于2时题目叫我们什么也不做
14             else if(now == 1){    // 等于1是要输出指数0
15                 cout<<"(0)";
16             }
17             /*
18             当当前指数分解结束后,要用之前的数减去当前分解的指数,比            
19             如这里137 = 2^7 + 2^3 + 2^0,在分解完2^7后,继续分解 
20             2^3 + 2^0
21             */
22             n -= now;        
23             if(n){         // 当然,如果可以继续分解的话,否则这里条件判断是假
24                 cout<<"+2";
25             }
26         }
27     }
28 }                          

 

完整代码

 1 #include<iostream> 
 2 
 3 using namespace std;
 4 
 5 void fun(int n)
 6 {
 7     int now, e;
 8     for(e=0, now=1; now <= n; now<<=1, e++);
 9     cout<<"2";
10     for(;now>0;now>>=1, e--){
11         if(now&n){
12             if(now > 2){
13                 cout<<"(";
14                 fun(e);
15                 cout<<")";
16             }
17             if(now == 2);
18             else if(now == 1){
19                 cout<<"(0)";
20             }
21             n -= now;
22             if(n){
23                 cout<<"+2";
24             }
25         }
26     }
27 }
28 int main()
29 {
30     int n = 0;
31     cin>>n;
32     fun(n);
33     
34     return 0;
35 }
View Code

 


 

posted @ 2018-10-30 23:12  maybeTang  阅读(3169)  评论(0编辑  收藏  举报