1、什么是循环语句

2、什么是O(n)时间与空间消耗

1、在上面的介绍图中,我们已经可以清晰的学习到什么是循环的概念。

2、当一个循环语句执行完成的时候,其所消耗的时间,我们称之为:时间复杂度,使用一个大写的O表示。

3、在该循环语句中,内部所执行的代码,我们称之为空间复杂度,使用一个()所表示。

4、根据循环的嵌套深度,所决定该循环语句的空间复杂程度,其深度我们使用 n^深度 所表示,例如:n^2。也可以将其中的^符号省略,简写成:n2

5、假设我们只有一个循环,并且内部并不嵌入更多的循环语句,那么完整的表达式应该为:O(n)

6、注意:在没有循环的代码中,我们也可以使用O(1),表示该代码已优化到极致。

在实际开发中,我们应该将尽可能的降低循环深度,以提高代码性能。

下面,我们来通过一张示例图,更加清晰的学习到什么是O(n)时间空间复杂度!

这里我们先插入一段循环语句的解释代码,现在看不懂没关系,同学们学完之后可以回头理解下,现在看不懂没关系,:

  1. for ($i = 0; $i < $n; $i++) {
  2. # 时间复杂度为O(1)的程序步骤序列
  3. }
  4. while ($count < $n) {
  5. $count = $count * 2;
  6. # 时间复杂度为O(1)的程序步骤序列
  7. # 由于每次count乘以2之后,就距离n更近了一分。
  8. # 也就是说,有多少个2相乘后大于n,则会退出循环。
  9. # 由2^x=n 得到x=logn。
  10. # 所以这个循环的时间复杂度可以用 O(logn) 公式表示。
  11. }
  12. for ($i = 0; $i < $n; $i++) {
  13. for ($j = 0; $j < $n; $j++) {
  14. # 而对于外层的循环,不过是内部这个时间复杂度为O(n)的语句,再循环n次。
  15. # 所以这段代码嵌套了1个循环,时间复杂度为 O(n^2)。
  16. }
  17. }
  18. for ($i = 0; $i < $m; $i++) {
  19. for ($j = 0; $j < $n; $j++) {
  20. # 基于上面的代码,我们将外层的$n改成了$m
  21. # 所以这段代码嵌套了1个循环,时间复杂度为 O(m*n)。
  22. }
  23. }

3、for数字循环

for()循环,是在您已经提前确定了脚本循环的次数的前提下,所优先选择的一种循环语句。

其语法介绍如下:

  1. 语法介绍如下:
  2. 表达式1:初始化循环计数器的值
  3. 表达式2:循环条件判断,true继续循环,false结束循环
  4. 表达式3:计数器的值加减变化
  5. for (表达式1; 表达式2; 表达式3) {
  6. 每次循环时,需要执行的代码
  7. }

假设,我们要循环显示 1*9 的数字,示例代码如下:

  1. <?php
  2. # 共循环9次
  3. for ($i=1; $i<=9; $i++) {
  4. echo '1*' .$i. '=' .(1*$i). '<br/>';
  5. }
  6. # 该循环的性能优化程度为O(n)

A、continue;跳出当次循环

在循环语句中,如果你在某些场景下,想跳过这一次的循环语句,直接进入下一次循环,可以使用continue关键字。

假设,我们要循环显示 1*9 的数字,但当循环到第5次的时候,我们会跳出这一次循环,不显示数字,示例代码如下:

  1. <?php
  2. # 共循环9次,第5次直接跳过
  3. for ($i=1; $i<=9; $i++) {
  4. if ($i==5) {
  5. continue; // 直接跳过当次循环,进入下一次循环
  6. }
  7. echo '1*' .$i. '=' .(1*$i). '<br/>';
  8. }
  9. # 该循环的性能优化程度为O(n)

B、break;终止循环

在循环语句中,如果你在某些场景下,想直接结束后面的所有循环语句,可以使用break关键字。

假设,我们要循环显示 1*9 的数字,但当循环到第3次的时候,我们会会直接结束后面的所有循环,示例代码如下:

  1. <?php
  2. # 共循环9次,第3次直接结束后面的所有循环
  3. for ($i=1; $i<=9; $i++) {
  4. if ($i==3) {
  5. break; // 直接结束后面的所有循环
  6. }
  7. echo '1*' .$i. '=' .(1*$i). '<br/>';
  8. }
  9. # 该循环的性能优化程度为O(n)

老师提醒:注意,breakcontinue关键字,在所有循环语句中,均可以使用。

C、练习题

使用for()语句,输出正9 X 9乘法表结构,提示:可使用多个循环嵌套实现。
显示的页面排版效果,应该如下:

  1. 1x1=1;
  2. 2x1=2; 2x2=4;
  3. ...

答案:下载

D、题外话

可能有些已经做完该练习的同学会发现,实际上理解两层for()循环嵌套,可以想象成是一张平面图,最外一层for()控制横,最里面一层的for()控制列。

想象法在编程中是最常用,也是最能锻炼思维能力的一种思想方式。

而在实际开发中,程序会经常出现bug,如果每一处都需要调试才能追寻到问题的根源,那么将会严重影响工作效率。

如果用想象法在脑海中模拟代码的运行,追寻可能出现bug的地方再逐一排查,那么就可以很轻易的找出问题根源。

两层for()循环我们可以看成是一张平面图,那要是三层for()嵌套呢?一般两层以上for()嵌套的时候,我们可以想象成多维空间,用思维模拟其运行。这是一种极其锻炼思维的方法。

先天天赋不高的同学不用灰心,天赋是可以随着编程的经验和思维的锻炼逐渐提升的,一般中品灵根的学生,模拟三层for()运行是完全可以做到的事情。

4、foreach数组循环

foreach()循环语句只适用于数组,用于循环读取数组中的每个键名 和 键值。

其语法介绍如下:

  1. foreach (数组变量 as $key=>$val) {
  2. 每循环一次,读取一行数组内容,从上往下执行,直到所有循环结束
  3. }

上面语法介绍中,变量$key$val只是示例说明,在实际开发中,你可以改写成任意变量名称;

每一次循环读取中,当前数组行数所对应的键名,会被存储在变量$key中;键值会被存储在变量$val中。

示例代码如下:

  1. <?php
  2. # 先定义一个实验数组,如果不自定义键名的情况下,PHP默认是从0开始的
  3. $data = [
  4. 1 => '小明',
  5. 2 => '宣言',
  6. 3 => '呵呵',
  7. ];
  8. # 使用foreach()语句循环读取数组内容
  9. foreach ($data as $k=>$v) {
  10. echo '键名:' .$k. ',键值:' .$v. '<br/>';
  11. }
  12. # 在某些情况下,如果你不需要用到键名,你可以使用下列方式,简写foreach()语句,默认$v部分只会读取键值
  13. foreach ($data as $v) {
  14. echo '键值:' .$v. '<br/>';
  15. }

A、练习题

定义一个二维数组,使用foreach()语句,结合之前对array数据类型的操作课程,实现循环输出二维数组里的键名 与 键值。

显示的页面排版效果,应该如下:

  1. 键名:1,键值:小明
  2. ...

答案:下载

5、while逻辑循环

当我们需要循环无限的执行下去,直到不再符合我们需要的条件时,才终止循环。这时候就可以使用到while系列的循环语句

A、while()

while()循环语句,是只要表达式一直为true时,循环就会无限的执行下去,其表达式如下:

  1. while (表达式为true时) {
  2. 要执行的代码块;
  3. }

假设,我们要循环显示 1*9 的数字,示例代码如下:

  1. <?php
  2. $i = 1; // 先定义初始数
  3. # 共循环9次
  4. while ($i<=9) {
  5. echo '1*' .$i. '=' .(1*$i). '<br/>';
  6. # $i自增1,到10的时候循环表达式将为false,自动结束循环
  7. $i++;
  8. }
  9. # 该循环的性能优化程度为O(n)

B、do{…}while()

do{...}while()和while()循环语句的区别是在于,do{...}while()语句会?先执行一次循环,然后再检测表达式是否为true,才会进入下一次循环,其表达式如下:

  1. do {
  2. 要执行的代码块;
  3. } while (表达式为true时);

假设,我们要循环显示 1*9 的数字,示例代码如下:

  1. <?php
  2. $i = 1; // 先定义初始数
  3. # 共循环9次
  4. do {
  5. echo '1*' .$i. '=' .(1*$i). '<br/>';
  6. # $i自增1,到10的时候循环表达式将为false,自动结束循环
  7. $i++;
  8. } while ($i<=9);
  9. # 该循环的性能优化程度为O(n)

老师提醒:不理解两种表达式的同学,可以尝试将上面的表达式直接修改为false,然后运行查看效果即可。

C、课后练习题

使用while()语句,输出正9 X 9乘法表结构。

显示的页面排版效果,应该如下:

  1. 1x1=1;
  2. 2x1=2; 2x2=4;
  3. ...

答案:下载