【程序设计】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")


在找到不相等的成员后跳出循环,在循环外部再判断。A3 的代码意味着,循环变量在循环结束之后仍然有值,而且如果循环是正常结束,其循环变量将被填成循环次数 +1,相当于假如还要进行一轮循环时循环变量应该的取值。

使用序列循环时,在循环结束后,循环变量将填成空值,并且循环序号也没有定义了。

【程序设计】 前言及目录
【程序设计】4.1 [排成队] 序列
【程序设计】4.3 [排成队] 多层序列