【程序设计】4.2 [排成队] 序列循环
4.2 序列循环
使用循环,我们可以实现一些针对序列的聚合运算,比如之前的 max/min。
A |
B |
C |
|
1 |
=[3,4,12,4,6,9,3,5] |
=-999999 |
=999999 |
2 |
for A1.len() |
if B1<A1(A2) |
>B1=A1(A2) |
3 |
if C1>A1(A2) |
>C1=A1(A2) |
A2 格中的 A1.len()将返回序列 A1 的长度,这种 x.f() 形式的函数我们在后面会再讲,现在先知道即可。
这是一段标准的计算最大最小值的算法。对于最大值,先设定目标值为一个很小的数,然后和序列成员依次比较,如果发现当前成员更大,则用当前成员替换目标值,等循环结束时就得到最大的值了。最小值是相反的过程。
求和也很简单:
A |
B |
|
1 |
=[3,4,12,4,6,9,3,5] |
=0 |
2 |
for A1.len() |
>B1+=A1(A2) |
不过,这里总要写个 A1.len(),后面引用成员时也要再用序号 A1(A2),有点麻烦。其实序列本身也可以被循环,max/min 可以这样写:
A |
B |
C |
|
1 |
=[3,4,12,4,6,9,3,5] |
=-999999 |
=999999 |
2 |
for A1 |
if B1<A2 |
>B1=A2 |
3 |
if C1>A2 |
>C1=A2 |
for 后面可以直接跟一个序列,循环次数就是序列的长度,而循环变量则依次是序列的每个成员。不需要再写序列长度了,也不需要使用序号来访问成员。
求和也一样很好写:
A |
B |
|
1 |
=[3,4,12,4,6,9,3,5] |
=0 |
2 |
for A1 |
>B1+=A2 |
近年来的程序设计语言开始纷纷支持这种集合式的循环写法,早期的程序语言没有很强的集合概念,只能用前面那种序号的写法。
不过,这样有个问题,我们不知道当前循环进行到第几轮了。比如,求最大值时,我们除了想知道最大值是几,还希望知道第几个成员最大。如果是前面的序号写法就比较简单:
A |
B |
C |
|
1 |
=[3,4,12,4,6,9,3,5] |
=-999999 |
=0 |
2 |
for A1.len() |
if B1<A1(A2) |
>B1=A1(A2) |
3 |
>C1=A2 |
在找到更大成员时把它的序号记下来就行了,最后 C1 中会是最大值的序号。
SPL 已经考虑到这一点,提供了方法能在序列循环时也能获得当前的循环轮次序号:
A |
B |
C |
|
1 |
=[3,4,12,4,6,9,3,5] |
=-999999 |
=0 |
2 |
for A1 |
if B1<A2 |
>B1=A2 |
3 |
>C1=#A2 |
序列循环时,有两个循环变量,循环格本身是序列成员,前面加了 #后表示循环轮次序号,在这里也就正好是期望的序列成员序号。这个加了# 的变量通常称为循环序号。
再看一例,我们来判断两个长度相同的序列是不是完全相同,也就是每个同序号的成员都相同,用常规的循环是这样的:
A |
B |
||
1 |
=[1,2,3,4,5] |
=[1,2,3,4,6] |
|
2 |
for A1.len() |
if A1(A2)!=B1(A2) |
>output("No") |
3 |
break |
如果发现不相等成员时输出 No,然后就跳出循环。
用循环序号实现也可以:
A |
B |
||
1 |
=[1,2,3,4,5] |
=[1,2,3,4,6] |
|
2 |
for A1 |
if A2!=B1(#A2) |
>output("No") |
3 |
break |
这段比较代码还可以这样写:
A |
B |
||
1 |
=[1,2,3,4,5] |
=[1,2,3,4,6] |
|
2 |
for A1.len() |
if A1(A2)!=B1(A2) |
break |
3 |
if A2<=A1.len() |
>output("No") |
使用序列循环时,在循环结束后,循环变量将填成空值,并且循环序号也没有定义了。