简体   繁体   English

减少时间复杂性

[英]Reducing time complexity

int main()
{
   int n ;
   std::cin >> n; // or scanf ("%d", &n);
   int temp;
   if( n ==1 ) temp = 1; // if n is 1 number is power of 2 so temp = 1
   if( n % 2 != 0 && n!= 1) temp =0; // if n is odd it can't be power of two
   else
   {
       for (;n && n%2 == 0; n /= 2);
       if(n  > 0 && n!= 1) temp = 0; // if the loop breaks out because of the second condition
       else temp = 1;
   }

   std::cout << temp; // or printf ("%d", temp);
}

The above code checks whether a number is power of two. 上面的代码检查数字是否为2的幂。 The worst case runtime complexity is O(n). 最坏的情况是运行时复杂度为O(n)。 How to optimize the code by reducing the time complexity? 如何通过减少时间复杂度来优化代码?

Try if( n && (n & (n-1)) == 0) temp = 1; 尝试if( n && (n & (n-1)) == 0) temp = 1; to check whether a number is power of two or not. 检查数字是否为2的幂。

For example : 例如 :

n = 16 ; n = 16 ;

  1 0 0 0 0 (n)
& 0 1 1 1 1 (n - 1)
  _________
  0 0 0 0 0 (yes)

A number which is power of 2 has only one bit set. 功率为2只有一位。

n & (n - 1) unsets the rightmost set bit . n & (n - 1) 取消设置最右边的设置位

Running time O(1) ;-) 运行时间O(1) ;-)

As @GMan noticed n needs to be an unsigned integer. 正如@GMan注意到, n需要是无符号整数。 Bitwise operation on negative signed integers is implementation defined. 负有符号整数的按位运算是实现定义的。

How about this? 这个怎么样?

bool IsPowerOfTwo(int value)
{
    return (value && ((value & (value-1)) == 0);
}

试试这个: bool isPowerOfTwo = n && !(n & (n - 1));

bool ifpower(int n)
{
    if(log2(n)==ceil(log2(n))) return true;
    else return false;
}

Instead of dividing a number by 2, you can right shift it by 1. This is an universal optimizing rule for division by 2,4,8,16,32 and so on. 您可以将数字右移1而不是将数字除以2.这是一个通用优化规则,用于除以2,4,8,16,32等。 This division can be replaced by right shift 1,2,3,4,5 and so on. 这种划分可以用右移1,2,3,4,5等代替。 They are mathematically equivalent. 它们在数学上是等价的。

Shift is better, because the assembler division instruction is terribly inefficient on most CPU architectures. Shift更好,因为汇编器除法指令在大多数CPU架构上都非常低效。 A logical shift right instruction is executed much faster. 逻辑右移指令执行得更快。

However , the compiler should be able to do this optimization for you, or it has a pretty bad optimizer. 但是 ,编译器应该能够为您执行此优化,或者它具有非常糟糕的优化器。 Style-wise it may be better to write division and modulo operators in the C code, but verify that the compiler actually optimizes them to shift operations. 在样式方面,在C代码中编写除法和模运算符可能更好,但验证编译器实际上是优化它们以转换操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM