是该程序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;
}
}
答案 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 = 1
和n = 1000000
上的函数运行时间不同,则您的函数不是O(1)
,即它没有恒定的时间复杂度。
让我们计算第一个函数终止所需的步数:
n / 2 x =1⇒x= log(n)
然而,对于第二个,理论上它将永远地将n
除以2,但实际上,它将在一些log(n) + c
步之后终止,在这种情况下,常量将被省略,并且复杂性将再次为log(n)
。