C#基础系列(2)-- 第一部分 基础数据类型与操作 -- 位运算(2)

问题2:请写一个方法判断一个整数是否是2的n次方
相信你能马上写出如下的算法

  1. //判断一个整数是否是2的n次方
  2. public static bool IsPower(int number)
  3. {
  4.     if (number <= 0)
  5.     {
  6.         return false;
  7.     }
  8.     if ((number & (number - 1)) == 0)
  9.     {
  10.         return true;
  11.     }
  12.     return false;
  13. }

初学写成这样确实不错,我们用到了位运算,但事实上,貌似和没有用的时候算法效率差不多。(提一个额外的话题,在写程序时尽量使用复合赋值运算符号,比如 i++的效率比 i += 1要高, i += 1 又比 i = i + 1要高)

但再仔细考虑一下,2的n次方会有什么特点?那就是其二进制表示只有1个1,那我们又怎么能知道其二进制表示只有1个1呢?

想了两天,突然想到,如果是整数8,其二进制表示形式是00001000,减去1后为00000111,而这两者位与的结果刚好是0

所以就有了下面的算法

  1. //判断一个整数是否是2的n次方
  2. public static bool IsPower(int number)
  3. {
  4.     if (number <= 0)
  5.     {
  6.         return false;
  7.     }
  8.     while (true)
  9.     {
  10.         if (number == 1)
  11.         {
  12.             return true;
  13.         }
  14.         //如果是奇数
  15.         if ((number & 1) == 1)
  16.         {
  17.             return false;
  18.         }
  19.         //右移一位
  20.         number >>= 1;
  21.     }
  22. }
  23. public static void Main()
  24. {
  25.     Console.WriteLine(IsPower(-8));
  26.     Console.WriteLine(IsPower(0));
  27.     Console.WriteLine(IsPower(1));
  28.     Console.WriteLine(IsPower(2));
  29.     Console.WriteLine(IsPower(5));
  30.     Console.WriteLine(IsPower(9));
  31.     Console.WriteLine(IsPower(12));
  32.     Console.WriteLine(IsPower(16));
  33. }


这个算法的效率一次循环都没做当然要比上面的高(事实上下面的算法时间复杂度是O(1),而上面的算法时间复杂度是O(n))

好的,让我们更进一步

问题3:对字节变量,其二进制表示法中求有多少个1,如 00101010则返回值为 3,也是要求效率最高

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值