我正在浏览以下链接enter link description here并通过答案我想计算以下建议代码的时间复杂度。我玩了很多值,步数在23(即使是小值)之间徘徊,并说50为真正的大值。我应该如何计算以下代码的时间复杂度 - 任何指针?
float val, low, high, mid, oldmid, midsqr;
// Set initial bounds and print heading.
low = 0; high = mid = val; oldmid = -1;
// Keep going until accurate enough.
while (fabs(oldmid - mid) >= 0.00001)
{
oldmid = mid;
// Get midpoint and see if we need lower or higher.
mid = (high + low) / 2;
midsqr = mid * mid;
if (mid * mid > val)
{
high = mid;
printf("- too high\n");
}
else
{
low = mid;
printf("- too low\n");
}
}
答案 0 :(得分:5)
在确定时间复杂度方面,请考虑有多少"步骤"你的算法将终止。
在这种情况下,我们基本上是二元搜索来找到平方根。因此,我们需要考虑的步骤数量是您的算法进行了多少次比较。因为它是二进制搜索,我们知道它在O(log(n))
的范围内,因为您可以将二进制搜索视为每次将可搜索空间减半。
所以现在我们需要弄清n
是什么。我们正在搜索范围(low, high)
,即(0, val)
。但是因为我们正在搜索浮点数,并且你关心的精度最高为0.00001
,我们可以有效地将范围乘以100000
,以便我们能够考虑整数问题。
然后我们将O(log(100000 * val))
的时间复杂度放在O(log(val))
中(除非精度不是常数)。
答案 1 :(得分:1)
您应该将您呈现的算法识别为二进制搜索。因为你首先进行了复杂性分析,我认为你知道二进制搜索的复杂性是O(log N)
。
主要的潜在并发症是N
适用于此问题的问题。你可能会想到它是你试图确定的平方根(即正方形)的值,但这只是近似正确的。相反,它是搜索空间中不同点的数量。这取决于搜索空间的范围以及您在其中的数字标准是不同的(在这种情况下,它们相差超过0.00001
)。
由于可表示的浮点数不是均匀分布的,因此它不像(upper_bound - lower_bound) / 0.00001
那么简单,但您可以将其作为粗略近似。此外,如果您使用0
作为下限,并使用方形的固定倍数(可能是1)作为上限,则该近似值会将O(log square)
作为整体复杂度。
现在考虑因为算法以对数方式缩放,所以搜索空间的大小加倍会在搜索的最大步数中产生固定的增量。由于它特别是二元搜索,因此一次运行与另一次运行之间的27步之差应该对应于搜索空间大小约2 27 (大约127,000,000)的因子。