while
代码结构如下,
while (/* condition */)
{
/* code */
}
可以分为几个相似的子类,下面分别讨论。
可以转化为等价的单变量for循环
i = 1;
while (i <= n - 1)
{
// 分析此处频度
i++;
}
可以转化为等价的python语句,
for i in range(1, n):
# 分析此处频度
容易看出,循环体中的代码将执行 次,复杂度为
.
涉及双变量的循环
i = 1;
j = 0;
while (i + j <= n)
{
// 分析此处频度
if (i > j)
j++;
else
i++;
}
可以把理解为二维平面上点的坐标。经画图分析可知,
的运动轨迹是一条从
开始,到直线
右侧结束的折线(图略)。根据
的奇偶,折线结束时的行为有所不同。将频度与
的关系计算用代码呈现出来,
def my_f6(n):
if n % 2 == 0:
return n / 2
else:
return n // 2 + 1
涉及科学计算
如,
x = n;
y = 0;
while (x >= (y + 1) * (y + 1))
{
// 分析此处频度
}
容易看出,
def my_f7(n):
return int(n ** .5 - 1) + 1
分频器型
x = 91;
y = 100;
while (y > 0)
{
// 分析此处频度
if (x > 100)
{
x -= 10;
y--;
}
else
x++;
}
本来,待分析代码只要执行100次,但由于迟滞变量x的存在,y递减的速度放慢了10倍。
do ... while
代码结构,
do
{
/* code */
} while (/* condition */);
总是可以将do...while循环转化为等价的while循环,方法是:用while句取代do句,并在while句前添加循环体中的语句。 即,变为,
/* code */
while (/* condition */)
{
/* code */
}
例
i = 1;
do
{
// 分析此处频度
i++;
} while (i <= n - 1);
可以转化成等价的while循环,为,
i = 1;
// 分析此处频度
while (i < n) {
// 分析此处频度
i++;
}
进一步转化为,
# 分析此处频度
for i in range(1, n):
# 分析此处频度
容易看出,此例与前例的差别在于待分析语句在进入循环前已经执行了一次。自然,此例的频度为.
for
这种循环和求和符号类似,结构为,
for (size_t i = 0; i < count; i++)
{
/* code */
}
即,
for i in range(n):
# code
两层嵌套
例如,
for (i = 1; i <= n; i++)
{
for (j = i; j <= n; j++)
// 分析此处频度
}
转化为求和式,
三层嵌套
如,
for (i = 1; i <= n; i++)
for (j = 1; j <= i; j++)
for (k = 1; k <= j; k++)
// 分析此处频度
转化为求和式,
注意,这里涉及到,
计算方法是:考虑如下伸缩级数,
两边展开,再利用
可得
附录
全部测试代码如下,
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import numpy as np
import matplotlib.pyplot as plt
# In[2]:
def f4(n):
k = 0
for i in range(1, n + 1):
for j in range(i, n + 1):
k += 1
return k
# In[3]:
def f5(n):
x = 0
for i in range(1, n + 1):
for j in range(1, i + 1):
for k in range(1, j + 1):
x += 1
return x
# In[4]:
def f6(n):
i = 1
j = 0
while i + j <= n:
if i > j:
j += 1
else:
i += 1
return j
# In[5]:
def f7(n):
x = n
y = 0
while (x >= (y + 1) ** 2):
y += 1
return y
# In[6]:
def f8(n):
x = 91
y = n
k = 0
while y > 0:
k += 1
if (x > 100):
x -= 10
y -= 1
else:
x += 1
return k
# In[7]:
def functionEqual(f1, f2):
x = np.random.randint(1000, size=10)
y1 = np.empty_like(x)
for i in range(len(x)):
y1[i] = f1(x[i])
y2 = np.empty_like(x)
for i in range(len(x)):
y2[i] = f2(x[i])
flag = True
for i in range(len(x)):
if y1[i] != y2[i]:
flag = False
break
return flag
# In[8]:
def my_f4(n):
return n * (n + 1) / 2
# In[9]:
def my_f5(n):
return n * (n + 1) * (n + 2) / 6
# In[10]:
def my_f6(n):
if n % 2 == 0:
return n / 2
else:
return n // 2 + 1
# In[11]:
def my_f7(n):
return int(n ** .5 - 1) + 1
# In[12]:
def my_f8(n):
return 11 * n
# In[13]:
check = [
functionEqual(f4, my_f4),
functionEqual(f5, my_f5),
functionEqual(f6, my_f6),
functionEqual(f7, my_f7),
functionEqual(f8, my_f8)
]
print(check)