← 学习库 Think Python (2e) · 中英对照 目录

Chapter 5  Conditionals and recursion 第 5 章 条件与递归

本页译自 Think Python 2e(Allen B. Downey)· Chapter 5 Conditionals and recursion。代码块保留英文原文不翻译;正文段段对照,中文块可用右下角按钮隐藏。

5.1 Modulus operator 5.1 取模运算符

The modulus operator works on integers and yields the remainder when the first operand is divided by the second. In Python, the modulus operator is a percent sign (%). The syntax is the same as for other operators:

取模运算符作用于整数,返回第一个操作数除以第二个操作数之后的余数。在 Python 中,取模运算符是百分号(%)。它的语法与其他运算符相同:
%00000006

So 7 divided by 3 is 2 with 1 left over.

所以 7 除以 3 等于 2,余数为 1。

The modulus operator turns out to be surprisingly useful. For example, you can check whether one number is divisible by another—if %0000 is zero, then % is divisible by %.

取模运算符其实出奇地有用。例如,你可以检查一个数能否被另一个数整除——如果 %0000 为零,那么 % 能被 % 整除。

Also, you can extract the right-most digit or digits from a number. For example, %00000 yields the right-most digit of % (in base 10). Similarly %000000 yields the last two digits.

此外,你可以从一个数字中提取最右边的一位或多位数字。例如,%00000 给出 % 的最右一位(以十进制计)。类似地,%000000 给出最后两位。

5.2 Boolean expressions 5.2 布尔表达式

A boolean expression is an expression that is either true or false. The following examples use the operator %0, which compares two operands and produces %000 if they are equal and %0000 otherwise:

布尔表达式是一种要么为真、要么为假的表达式。下面的例子使用了运算符 %0,它比较两个操作数:若相等则产生 %000,否则产生 %0000:
%00000025

%000 and %0000 are special values that belong to the type %000; they are not strings:

%000 和 %0000 是特殊的值,属于 %000 类型;它们不是字符串:
%00000032

The %0 operator is one of the relational operators; the others are:

%0 运算符是关系运算符之一;其余的如下:
%00000035

Although these operations are probably familiar to you, the Python symbols are different from the mathematical symbols. A common error is to use a single equal sign (%) instead of a double equal sign (%0). Remember that % is an assignment operator and %0 is a relational operator. There is no such thing as %0000 or %0000.

虽然这些运算你可能很熟悉,但 Python 的符号与数学符号不同。一个常见错误是用单个等号(%)代替双等号(%0)。记住,% 是赋值运算符,而 %0 是关系运算符。不存在 %0000 或 %0000 这样的东西。

5.3 Logical operators 5.3 逻辑运算符

There are three logical operators: %00, %0, and %00. The semantics (meaning) of these operators is similar to their meaning in English. For example, %00000051 is true only if % is greater than 0 and less than 10.

共有三种逻辑运算符:%00、%0 和 %00。这些运算符的语义(含义)与它们在英语中的意思相近。例如,%00000056 仅当 % 大于 0 且小于 10 时才为真。

%00000058 is true if either of the conditions is true, that is, if the number is divisible by 2 or 3.

%00000059 在两个条件中任一为真时为真,也就是说,当该数能被 2 或 3 整除时为真。

Finally, the %00 operator negates a boolean expression, so %00000061 is true if %0000006 is false, that is, if % is less than or equal to %.

最后,%00 运算符对布尔表达式取反,所以 %00000066 在 %0000006 为假时为真,也就是说,当 % 小于或等于 % 时为真。

Strictly speaking, the operands of the logical operators should be boolean expressions, but Python is not very strict. Any nonzero number is interpreted as "true."

严格来说,逻辑运算符的操作数应当是布尔表达式,但 Python 并不严谨。任何非零数字都被当作「真」。
%00000070

This flexibility can be useful, but there are some subtleties to it that might be confusing. You might want to avoid it (unless you know what you are doing).

这种灵活性有时很有用,但其中有些微妙之处可能令人困惑。也许最好避开它(除非你知道自己在做什么)。

5.4 Conditional execution 5.4 条件执行

In order to write useful programs, we almost always need the ability to check conditions and change the behavior of the program accordingly. Conditional statements give us this ability. The simplest form is the %0 statement:

为了写出有用的程序,我们几乎总需要检查条件并据此改变程序的行为。条件语句赋予我们这种能力。最简单的形式是 %0 语句:
%00000073

The boolean expression after %0 is called the condition. If it is true, then the indented statement gets executed. If not, nothing happens.

%0 之后的布尔表达式称为条件。若为真,则缩进的语句会被执行;否则什么也不会发生。

%0 statements have the same structure as function definitions: a header followed by an indented body. Statements like this are called compound statements.

%0 语句与函数定义结构相同:一个头部,后跟一个缩进的主体。这样的语句称为复合语句。

There is no limit on the number of statements that can appear in the body, but there has to be at least one. Occasionally, it is useful to have a body with no statements (usually as a place keeper for code you haven’t written yet). In that case, you can use the %000 statement, which does nothing.

主体中可以出现任意多条语句,但至少得有一条。有时,拥有一个不含语句的主体很有用(通常作为尚未写好的代码的占位符)。这时可以使用 %000 语句,它什么也不做。
%00000080

5.5 Alternative execution 5.5 二选一执行

A second form of the %0 statement is alternative execution, in which there are two possibilities and the condition determines which one gets executed. The syntax looks like this:

%0 语句的第二种形式是二选一执行,其中有两种可能,由条件决定执行哪一个。语法如下:
%00000083

If the remainder when % is divided by 2 is 0, then we know that % is even, and the program displays a message to that effect. If the condition is false, the second set of statements is executed. Since the condition must be true or false, exactly one of the alternatives will be executed. The alternatives are called branches, because they are branches in the flow of execution.

如果 % 除以 2 的余数等于 0,我们就知道 % 是偶数,程序会显示相应的信息。如果条件为假,则执行第二组语句。由于条件非真即假,两种可能中恰好有一种会被执行。这些可能称为分支,因为它们是执行流中的分支。

5.6 Chained conditionals 5.6 链式条件

Sometimes there are more than two possibilities and we need more than two branches. One way to express a computation like that is a chained conditional:

有时会有两种以上的可能,我们需要两个以上的分支。表达这类计算的一种方式就是链式条件:
%00000088

%000 is an abbreviation of "else if." Again, exactly one branch will be executed. There is no limit on the number of %000 statements. If there is an %000 clause, it has to be at the end, but there doesn’t have to be one.

%000 是「else if」的缩写。同样,恰好有一个分支会被执行。%000 语句的数量没有限制。如果有 %000 子句,它必须放在最后,但也可以没有。
%00000095

Each condition is checked in order. If the first is false, the next is checked, and so on. If one of them is true, the corresponding branch executes, and the statement ends. Even if more than one condition is true, only the first true branch executes.

每个条件会按顺序检查。如果第一个为假,就检查下一个,依此类推。一旦其中某个为真,相应的分支就会执行,语句随之结束。即使有多个条件为真,也只有第一个为真的分支会执行。

5.7 Nested conditionals 5.7 嵌套条件

One conditional can also be nested within another. We could have written the trichotomy example like this:

一个条件也可以嵌套在另一个条件之中。前面三分支的例子也可以这样写:
%00000096

The outer conditional contains two branches. The first branch contains a simple statement. The second branch contains another %0 statement, which has two branches of its own. Those two branches are both simple statements, although they could have been conditional statements as well.

外层条件包含两条分支。第一条分支是简单语句。第二条分支包含另一个 %0 语句,它自身又有两个分支。那两个分支都是简单语句,不过它们同样可以是条件语句。

Although the indentation of the statements makes the structure apparent, nested conditionals become difficult to read very quickly. In general, it is a good idea to avoid them when you can.

尽管语句的缩进让结构一目了然,嵌套条件很快就会变得难以阅读。一般来说,能避开时就尽量避开。

Logical operators often provide a way to simplify nested conditional statements. For example, we can rewrite the following code using a single conditional:

逻辑运算符常常能简化嵌套条件语句。例如,我们可以用单个条件改写下面这段代码:
%00000099

The %0000 statement is executed only if we make it past both conditionals, so we can get the same effect with the %00 operator:

%0000 语句只有在两个条件都通过时才会执行,因此我们可以借助 %00 运算符获得同样的效果:
%00000104

5.8 Recursion 5.8 递归

It is legal for one function to call another; it is also legal for a function to call itself. It may not be obvious why that is a good thing, but it turns out to be one of the most magical things a program can do. For example, look at the following function:

一个函数调用另一个函数是合法的;一个函数调用自身同样合法。为什么这会是件好事也许并不明显,但它确实是程序能做出的最神奇的事情之一。例如,看看下面这个函数:
%00000105

If % is 0 or negative, it outputs the word, "Blastoff!" Otherwise, it outputs % and then calls a function named %00000108—itself—passing %00 as an argument.

如果 % 为 0 或负数,它输出「Blastoff!」这个词。否则,它输出 %,然后调用一个名为 %00000112 的函数——也就是它自己——并把 %00 作为参数传入。

What happens if we call this function like this?

如果我们像下面这样调用这个函数,会发生什么?
%00000114

The execution of %00000115 begins with %00, and since % is greater than 0, it outputs the value 3, and then calls itself...

%00000118 的执行从 %00 开始,由于 % 大于 0,它输出值 3,然后调用自身……

The execution of %00000121 begins with %00, and since % is greater than 0, it outputs the value 2, and then calls itself...

这次 %00000124 的执行从 %00 开始,由于 % 大于 0,它输出值 2,然后调用自身……

The execution of %00000127 begins with %00, and since % is greater than 0, it outputs the value 1, and then calls itself...

这次 %00000130 的执行从 %00 开始,由于 % 大于 0,它输出值 1,然后调用自身……

The execution of %00000133 begins with %00, and since % is not greater than 0, it outputs the word, "Blastoff!" and then returns.

这次 %00000136 的执行从 %00 开始,由于 % 不大于 0,它输出「Blastoff!」这个词,然后返回。

The %00000139 that got %00 returns.

拿到 %00 的那次 %00000142 返回。

The %00000143 that got %00 returns.

拿到 %00 的那次 %00000146 返回。

The %00000147 that got %00 returns. And then you’re back in %0000014. So, the total output looks like this:

拿到 %00 的那次 %00000151 返回。然后你就回到了 %0000015。于是,整体输出如下:
%00000153

A function that calls itself is recursive; the process is called recursion.

调用自身的函数称为递归的;这个过程称为递归。

As another example, we can write a function that prints a string % % times.

再举一个例子,我们可以写一个函数,把字符串 % 打印 % 次。
%00000158

If %00000159 the %00000 statement exits the function. The flow of execution immediately returns to the caller, and the remaining lines of the function are not executed.

如果 %00000161,%00000 语句会退出函数。执行流立即返回到调用者,函数中剩余的行不再执行。

The rest of the function is similar to %00000163: if % is greater than 0, it displays % and then calls itself to display % n−1 additional times. So the number of lines of output is %00000167, which adds up to %.

函数的其余部分与 %00000169 类似:如果 % 大于 0,它就显示 %,然后调用自身再显示 %n−1 次。所以输出的行数是 %00000173,相加等于 %

For simple examples like this, it is probably easier to use a %00 loop. But we will see examples later that are hard to write with a %00 loop and easy to write with recursion, so it is good to start early.

对于这样的简单例子,用 %00 循环或许更轻松。但稍后我们会看到一些用 %00 循环很难写、用递归却很容易的例子,所以早点开始是件好事。

5.9 Stack diagrams for recursive functions 5.9 递归函数的栈图

In Section 3.10, we used a stack diagram to represent the state of a program during a function call. The same kind of diagram can help interpret a recursive function.

在第 3.10 节中,我们用栈图来表示函数调用期间程序的状态。同样类型的图也能帮助理解递归函数。

Every time a function gets called, Python creates a new function frame, which contains the function’s local variables and parameters. For a recursive function, there might be more than one frame on the stack at the same time.

每当一个函数被调用,Python 都会创建一个新的函数栈帧,其中包含该函数的局部变量和形参。对于递归函数,栈上可能同时有多个栈帧。

Figure 5.1 shows a stack diagram for %00000179 called with %0000.

图 5.1 展示了以 %0000 调用 %00000182 时的栈图。

Figure 5.1: Stack diagram.

图 5.1:栈图(原书插图未收录)

As usual, the top of the stack is the frame for %0000018. It is empty because we did not create any variables in %0000018 or pass any arguments to it.

和往常一样,栈顶是 %0000018 的栈帧。它是空的,因为我们没有在 %0000018 中创建任何变量,也没有向它传入任何参数。

The four %00000187 frames have different values for the parameter %. The bottom of the stack, where %00, is called the base case. It does not make a recursive call, so there are no more frames.

四个 %00000190 栈帧中,形参 % 的值各不相同。栈底(%00 处)称为基础情形。它不再进行递归调用,因此没有更多栈帧。

Exercise 1 Draw a stack diagram for %000001 called with %00000194 and %00.

习题 1 画出以 %00000196、%00 调用 %000001 时的栈图。

Exercise 2 Write a function called %000 that takes a function object and a number, %, as arguments, and that calls the given function % times.

习题 2 写一个名为 %000 的函数,它接受一个函数对象和一个数字 % 作为参数,并把给定的函数调用 % 次。

5.10 Infinite recursion 5.10 无限递归

If a recursion never reaches a base case, it goes on making recursive calls forever, and the program never terminates. This is known as infinite recursion, and it is generally not a good idea. Here is a minimal program with an infinite recursion:

如果递归永远到达不了基础情形,它就会一直进行递归调用,程序永远不会终止。这称为无限递归,通常来说不是个好主意。下面是一个带有无限递归的最小程序:
%00000205

In most programming environments, a program with infinite recursion does not really run forever. Python reports an error message when the maximum recursion depth is reached:

在大多数编程环境中,带有无限递归的程序并不会真的永远运行下去。当达到最大递归深度时,Python 会报告一个错误信息:
%00000206

This traceback is a little bigger than the one we saw in the previous chapter. When the error occurs, there are 1000 %000002 frames on the stack!

这个回溯比上一章看到的那个稍大一些。错误发生时,栈上有 1000 个 %000002 栈帧!

5.11 Keyboard input 5.11 键盘输入

The programs we have written so far are a bit rude in the sense that they accept no input from the user. They just do the same thing every time.

到目前为止我们写的程序有点粗鲁——它们不接受用户的任何输入,每次都做同样的事。

Python 2 provides a built-in function called %00000209 that gets input from the keyboard. In Python 3, it is called %0000. When this function is called, the program stops and waits for the user to type something. When the user presses Return or Enter, the program resumes and %00000211 returns what the user typed as a string.

Python 2 提供了一个名为 %00000212 的内置函数,用来从键盘获取输入。在 Python 3 中,它叫 %0000。调用这个函数时,程序会停下来等待用户输入。当用户按下回车或 Enter 键,程序继续运行,%00000214 会返回用户所输入的内容,类型为字符串。
%00000215

Before getting input from the user, it is a good idea to print a prompt telling the user what to input. %00000216 can take a prompt as an argument:

在向用户获取输入之前,最好先打印一条提示,告诉用户要输入什么。%00000217 可以接受一个提示作为实参:
%00000218

The sequence %0 at the end of the prompt represents a newline, which is a special character that causes a line break. That’s why the user’s input appears below the prompt.

提示末尾的序列 %0 表示一个换行符(newline),它是一种特殊字符,会引起换行。所以用户的输入会出现在提示的下一行。

If you expect the user to type an integer, you can try to convert the return value to %00:

如果你希望用户输入整数,可以尝试把返回值转换成 %00:
%00000223

But if the user types something other than a string of digits, you get an error:

但如果用户输入的不是一串数字,就会得到一个错误:
%00000224

We will see how to handle this kind of error later.

稍后我们会看到如何处理这类错误。

5.12 Debugging 5.12 调试

The traceback Python displays when an error occurs contains a lot of information, but it can be overwhelming, especially when there are many frames on the stack. The most useful parts are usually:

发生错误时 Python 显示的回溯包含大量信息,但可能让人难以招架,尤其是栈上有很多栈帧的时候。最有用的部分通常是:

Syntax errors are usually easy to find, but there are a few gotchas. Whitespace errors can be tricky because spaces and tabs are invisible and we are used to ignoring them.

语法错误通常容易找到,但也有一些陷阱。空白错误可能很棘手,因为空格和制表符不可见,而我们已经习惯忽略它们。
%00000225

In this example, the problem is that the second line is indented by one space. But the error message points to %, which is misleading. In general, error messages indicate where the problem was discovered, but the actual error might be earlier in the code, sometimes on a previous line.

在这个例子中,问题是第二行多缩进了一个空格。但错误信息指向 %,这会产生误导。一般来说,错误信息指示的是问题被发现的位置,而真正的错误可能出现在更早的代码里,有时在前一行。

The same is true of runtime errors.

运行时错误同样如此。

Suppose you are trying to compute a signal-to-noise ratio in decibels. The formula is SNRdb = 10 log10 (Psignal / Pnoise). In Python, you might write something like this:

假设你要计算信噪比(以分贝计)。公式为 SNRdb = 10 log10Psignal / Pnoise)。在 Python 中,你可能会这样写:
%00000228

But when you run it in Python 2, you get an error message.

但在 Python 2 中运行它时,你会得到一个错误信息。
%00000229

The error message indicates line 5, but there is nothing wrong with that line. To find the real error, it might be useful to print the value of %0000, which turns out to be 0. The problem is in line 4, because dividing two integers does floor division. The solution is to represent signal power and noise power with floating-point values.

错误信息指向第 5 行,但那一行并没有问题。要找到真正的错误,打印一下 %0000 的值也许有帮助,结果它等于 0。问题出在第 4 行,因为两个整数相除执行的是整除(floor division)。解决办法是用浮点数值来表示信号功率和噪声功率。

In general, error messages tell you where the problem was discovered, but that is often not where it was caused.

一般来说,错误信息告诉你的是问题被发现的位置,但那往往不是问题产生的地方。

In Python 3, this example does not cause an error; the division operator performs floating-point division even with integer operands.

在 Python 3 中,这个例子不会引发错误;即使操作数是整数,除法运算符也会执行浮点除法。

5.13 Glossary 5.13 术语表

modulus operator:
An operator, denoted with a percent sign (%), that works on integers and yields the remainder when one number is divided by another.
boolean expression:
An expression whose value is either %000 or %0000.
relational operator:
One of the operators that compares its operands: %0, %0, %000, %000, %0000, and %0000.
logical operator:
One of the operators that combines boolean expressions: %00, %0, and %00.
conditional statement:
A statement that controls the flow of execution depending on some condition.
condition:
The boolean expression in a conditional statement that determines which branch is executed.
compound statement:
A statement that consists of a header and a body. The header ends with a colon (:). The body is indented relative to the header.
branch:
One of the alternative sequences of statements in a conditional statement.
chained conditional:
A conditional statement with a series of alternative branches.
nested conditional:
A conditional statement that appears in one of the branches of another conditional statement.
recursion:
The process of calling the function that is currently executing.
base case:
A conditional branch in a recursive function that does not make a recursive call.
infinite recursion:
A recursion that doesn’t have a base case, or never reaches it. Eventually, an infinite recursion causes a runtime error.
modulus operator 取模运算符:
一种用百分号(%)表示的运算符,作用于整数,返回一个数除以另一个数时的余数。
boolean expression 布尔表达式:
值要么为 %000、要么为 %0000 的表达式。
relational operator 关系运算符:
用来比较操作数的运算符之一:%0、%0、%000、%000、%0000 和 %0000。
logical operator 逻辑运算符:
用来组合布尔表达式的运算符之一:%00、%0 和 %00。
conditional statement 条件语句:
依据某个条件来控制执行流的语句。
condition 条件:
条件语句中决定执行哪个分支的布尔表达式。
compound statement 复合语句:
由头部和主体构成的语句。头部以冒号(:)结尾。主体相对头部缩进。
branch 分支:
条件语句中若干备选语句序列之一。
chained conditional 链式条件:
带有一系列备选分支的条件语句。
nested conditional 嵌套条件:
出现在另一个条件语句的某个分支中的条件语句。
recursion 递归:
调用当前正在执行的函数这一过程。
base case 基础情形:
递归函数中不再进行递归调用的条件分支。
infinite recursion 无限递归:
没有基础情形、或永远到达不了基础情形的递归。最终,无限递归会引发运行时错误。

5.14 Exercises 5.14 习题

Exercise 3 Fermat’s Last Theorem says that there are no positive integers a, b, and c such that

an + bn = cn

for any values of n greater than 2.

习题 3 费马大定理指出:不存在正整数 abc 满足
an + bn = cn
对于任意大于 2 的 n
  1. Write a function named %00000256 that takes four parameters—%, %, % and %—and that checks to see if Fermat’s theorem holds. If n is greater than 2 and it turns out to be true that an + bn = cn, the program should print, "Holy smokes, Fermat was wrong!" Otherwise the program should print, "No, that doesn’t work."
  2. Write a function that prompts the user to input values for %, %, % and %, converts them to integers, and uses %00000265 to check whether they violate Fermat’s theorem.
  1. 写一个名为 %00000266 的函数,它接受四个参数——%%%%——并检查费马定理是否成立。如果 n 大于 2 且确实有 an + bn = cn,程序应当打印「Holy smokes,费马错了!」;否则程序应当打印「No,那不成立。」
  2. 写一个函数,提示用户输入 %%%% 的值,把它们转换成整数,并用 %00000275 检查它们是否违背了费马定理。

Exercise 4 If you are given three sticks, you may or may not be able to arrange them in a triangle. For example, if one of the sticks is 12 inches long and the other two are one inch long, it is clear that you will not be able to get the short sticks to meet in the middle. For any three lengths, there is a simple test to see if it is possible to form a triangle:

习题 4 如果给你三根木棍,你也许能、也许不能把它们拼成一个三角形。例如,如果其中一根长 12 英寸,另外两根各长 1 英寸,显然你无法让这两根短棍在中间相接。对于任意三个长度,有一个简单的检验方法可以判断能否构成三角形:

If any of the three lengths is greater than the sum of the other two, then you cannot form a triangle. Otherwise, you can. (If the sum of two lengths equals the third, they form what is called a "degenerate" triangle.)

如果三段长度中有任意一段大于另外两段之和,就无法构成三角形;否则可以。(如果两段长度之和等于第三段,它们构成所谓「退化」三角形。)
  1. Write a function named %00000276 that takes three integers as arguments, and that prints either "Yes" or "No," depending on whether you can or cannot form a triangle from sticks with the given lengths.
  2. Write a function that prompts the user to input three stick lengths, converts them to integers, and uses %00000277 to check whether sticks with the given lengths can form a triangle.
  1. 写一个名为 %00000278 的函数,它接受三个整数作为参数,并根据给定长度的木棍能否构成三角形来打印「Yes」或「No」。
  2. 写一个函数,提示用户输入三根木棍的长度,把它们转换成整数,并用 %00000279 检查给定长度的木棍能否构成三角形。

The following exercises use TurtleWorld from Chapter 4:

下面几道习题用到第 4 章的 TurtleWorld:

Exercise 5 Read the following function and see if you can figure out what it does. Then run it (see the examples in Chapter 4).

习题 5 读一读下面的函数,看看能不能弄明白它的作用。然后运行它(参见第 4 章的例子)。
%00000280

Figure 5.2: A Koch curve.

图 5.2:科赫曲线(原书插图未收录)

Exercise 6 The Koch curve is a fractal that looks something like Figure 5.2. To draw a Koch curve with length x, all you have to do is

习题 6 科赫曲线是一种分形,看起来有点像图 5.2。要画一条长度为 x 的科赫曲线,你只需做以下事情
  1. Draw a Koch curve with length x/3.
  2. Turn left 60 degrees.
  3. Draw a Koch curve with length x/3.
  4. Turn right 120 degrees.
  5. Draw a Koch curve with length x/3.
  6. Turn left 60 degrees.
  7. Draw a Koch curve with length x/3.
  1. 画一条长度为 x/3 的科赫曲线。
  2. 左转 60 度。
  3. 画一条长度为 x/3 的科赫曲线。
  4. 右转 120 度。
  5. 画一条长度为 x/3 的科赫曲线。
  6. 左转 60 度。
  7. 画一条长度为 x/3 的科赫曲线。

The exception is if x is less than 3: in that case, you can just draw a straight line with length x.

例外情况是当 x 小于 3 时:这时你只需画一条长度为 x 的直线。
  1. Write a function called %000 that takes a turtle and a length as parameters, and that uses the turtle to draw a Koch curve with the given length.
  2. Write a function called %00000282 that draws three Koch curves to make the outline of a snowflake. Solution: %00000283.
  3. The Koch curve can be generalized in several ways. See %00000284 for examples and implement your favorite.
  1. 写一个名为 %000 的函数,它接受一只乌龟和一个长度作为参数,并用这只乌龟画出给定长度的科赫曲线。
  2. 写一个名为 %00000286 的函数,画出三条科赫曲线,构成雪花的轮廓。 参考解答:%00000287。
  3. 科赫曲线有几种推广方式。参见 %00000288 中的例子,并实现你最喜欢的一种。