这个函数的时间复杂度/大O是不变的吗?

时间:2018-03-13 19:41:50

标签: c loops time-complexity big-o complexity-theory

是该程序O(1)的时间复杂度?

f1(int n){
  int temp = n;
  while (temp /= 2))
  {
    len++; result+=m;
  }
}

如果我们将int temp改为double temp,那么时间复杂度是否也会改变,或者它会保持不变?

f2(int n){
  double temp = (double)n;
  while (temp /= 2))
  {
    len++; result+=m;
  }
}

2 个答案:

答案 0 :(得分:3)

整数部分的答案是private async void page_Loaded(object sender, RoutedEventArgs e) { var picker = new CastingDevicePicker(); picker.Filter.SupportsPictures = true; picker.CastingDeviceSelected += Picker_CastingDeviceSelected; picker.Show(new Windows.Foundation.Rect(50, 50, 100, 100)); } private async void Picker_CastingDeviceSelected(CastingDevicePicker sender, CastingDeviceSelectedEventArgs args) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => { CastingConnection connection = args.SelectedCastingDevice.CreateCastingConnection(); connection.ErrorOccurred += Connection_ErrorOccurred; connection.StateChanged += Connection_StateChanged; await connection.RequestStartCastingAsync(image.GetAsCastingSource()); }); } ,因为每次都会减半。

双版本以相同的方式开始,除了当值达到1或接近1时,它不会停止并分割,直到下溢使其为0.此时,分割数是固定的。 / p>

我制作了一个经验校准的小程序,试图预测循环次数:

O(log n)

我明白了:

#include <stdio.h>
#include <math.h>

void f2(int n){
  int len=0;
  double temp = (double)n;
  while (temp /= 2)
  {
    len++; 
  }
  // 1.53 is an empiric constant, maybe it could be theorically computed
  // it was just to make the numbers match
  printf("%d %lf\n",len,log(n)*1.53+1074);
}
int main()
{

    f2(100000000);
    f2(10000000);
    f2(1000000);
    f2(10000);
    f2(100);
    f2(1);

}

因此复杂性为1101 1102.183642 1097 1098.660686 1094 1095.137731 1087 1088.091821 1081 1081.045910 1074 1074.000000 加上不可压缩的迭代次数,具体取决于机器。

(我对我答案的经验方面表示道歉,我不是浮点专家)

答案 1 :(得分:2)

对于具有恒定时间复杂度的算法,随着输入数n的增长,其运行时应保持不变。如果n = 1n = 1000000上的函数运行时间不同,则您的函数不是O(1),即它没有恒定的时间复杂度。

让我们计算第一个函数终止所需的步数:

n / 2 x =1⇒x= log(n)

然而,对于第二个,理论上它将永远地将n除以2,但实际上,它将在一些log(n) + c步之后终止,在这种情况下,常量将被省略,并且复杂性将再次为log(n)