1、什么是循环语句
2、什么是O(n)时间与空间消耗
1、在上面的介绍图中,我们已经可以清晰的学习到什么是循环的概念。
2、当一个循环语句执行完成的时候,其所消耗的时间,我们称之为:时间复杂度,使用一个大写的O
表示。
3、在该循环语句中,内部所执行的代码,我们称之为空间复杂度,使用一个()
所表示。
4、根据循环的嵌套深度,所决定该循环语句的空间复杂程度,其深度我们使用 n^
深度 所表示,例如:n^2
。也可以将其中的^
符号省略,简写成:n2
。
5、假设我们只有一个循环,并且内部并不嵌入更多的循环语句,那么完整的表达式应该为:O(n)
6、注意:在没有循环的代码中,我们也可以使用O(1)
,表示该代码已优化到极致。
在实际开发中,我们应该将尽可能的降低循环深度,以提高代码性能。
下面,我们来通过一张示例图,更加清晰的学习到什么是O(n)
时间空间复杂度!
这里我们先插入一段循环语句的解释代码,现在看不懂没关系,同学们学完之后可以回头理解下,现在看不懂没关系,:
for ($i = 0; $i < $n; $i++) {
# 时间复杂度为O(1)的程序步骤序列
}
while ($count < $n) {
$count = $count * 2;
# 时间复杂度为O(1)的程序步骤序列
# 由于每次count乘以2之后,就距离n更近了一分。
# 也就是说,有多少个2相乘后大于n,则会退出循环。
# 由2^x=n 得到x=logn。
# 所以这个循环的时间复杂度可以用 O(logn) 公式表示。
}
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n; $j++) {
# 而对于外层的循环,不过是内部这个时间复杂度为O(n)的语句,再循环n次。
# 所以这段代码嵌套了1个循环,时间复杂度为 O(n^2)。
}
}
for ($i = 0; $i < $m; $i++) {
for ($j = 0; $j < $n; $j++) {
# 基于上面的代码,我们将外层的$n改成了$m
# 所以这段代码嵌套了1个循环,时间复杂度为 O(m*n)。
}
}
3、for数字循环
for()
循环,是在您已经提前确定了脚本循环的次数的前提下,所优先选择的一种循环语句。
其语法介绍如下:
语法介绍如下:
表达式1:初始化循环计数器的值
表达式2:循环条件判断,true继续循环,false结束循环
表达式3:计数器的值加减变化
for (表达式1; 表达式2; 表达式3) {
每次循环时,需要执行的代码
}
假设,我们要循环显示 1*9
的数字,示例代码如下:
<?php
# 共循环9次
for ($i=1; $i<=9; $i++) {
echo '1*' .$i. '=' .(1*$i). '<br/>';
}
# 该循环的性能优化程度为O(n)
A、continue;跳出当次循环
在循环语句中,如果你在某些场景下,想跳过这一次的循环语句,直接进入下一次循环,可以使用continue
关键字。
假设,我们要循环显示 1*9
的数字,但当循环到第5
次的时候,我们会跳出这一次循环,不显示数字,示例代码如下:
<?php
# 共循环9次,第5次直接跳过
for ($i=1; $i<=9; $i++) {
if ($i==5) {
continue; // 直接跳过当次循环,进入下一次循环
}
echo '1*' .$i. '=' .(1*$i). '<br/>';
}
# 该循环的性能优化程度为O(n)
B、break;终止循环
在循环语句中,如果你在某些场景下,想直接结束后面的所有循环语句,可以使用break
关键字。
假设,我们要循环显示 1*9
的数字,但当循环到第3
次的时候,我们会会直接结束后面的所有循环,示例代码如下:
<?php
# 共循环9次,第3次直接结束后面的所有循环
for ($i=1; $i<=9; $i++) {
if ($i==3) {
break; // 直接结束后面的所有循环
}
echo '1*' .$i. '=' .(1*$i). '<br/>';
}
# 该循环的性能优化程度为O(n)
老师提醒:注意,
break
与continue
关键字,在所有循环语句中,均可以使用。
C、练习题
使用for()
语句,输出正9 X 9
乘法表结构,提示:可使用多个循环嵌套实现。
显示的页面排版效果,应该如下:
1x1=1;
2x1=2; 2x2=4;
...
答案:下载
D、题外话
可能有些已经做完该练习的同学会发现,实际上理解两层for()
循环嵌套,可以想象成是一张平面图,最外一层for()
控制横,最里面一层的for()
控制列。
想象法在编程中是最常用,也是最能锻炼思维能力的一种思想方式。
而在实际开发中,程序会经常出现bug,如果每一处都需要调试才能追寻到问题的根源,那么将会严重影响工作效率。
如果用想象法在脑海中模拟代码的运行,追寻可能出现bug的地方再逐一排查,那么就可以很轻易的找出问题根源。
两层for()
循环我们可以看成是一张平面图,那要是三层for()
嵌套呢?一般两层以上for()
嵌套的时候,我们可以想象成多维空间,用思维模拟其运行。这是一种极其锻炼思维的方法。
先天天赋不高的同学不用灰心,天赋是可以随着编程的经验和思维的锻炼逐渐提升的,一般中品灵根的学生,模拟三层for()
运行是完全可以做到的事情。
4、foreach数组循环
foreach()
循环语句只适用于数组,用于循环读取数组中的每个键名 和 键值。
其语法介绍如下:
foreach (数组变量 as $key=>$val) {
每循环一次,读取一行数组内容,从上往下执行,直到所有循环结束
}
上面语法介绍中,变量$key
与$val
只是示例说明,在实际开发中,你可以改写成任意变量名称;
每一次循环读取中,当前数组行数所对应的键名,会被存储在变量$key
中;键值会被存储在变量$val
中。
示例代码如下:
<?php
# 先定义一个实验数组,如果不自定义键名的情况下,PHP默认是从0开始的
$data = [
1 => '小明',
2 => '宣言',
3 => '呵呵',
];
# 使用foreach()语句循环读取数组内容
foreach ($data as $k=>$v) {
echo '键名:' .$k. ',键值:' .$v. '<br/>';
}
# 在某些情况下,如果你不需要用到键名,你可以使用下列方式,简写foreach()语句,默认$v部分只会读取键值
foreach ($data as $v) {
echo '键值:' .$v. '<br/>';
}
A、练习题
定义一个二维数组,使用foreach()
语句,结合之前对array
数据类型的操作课程,实现循环输出二维数组里的键名 与 键值。
显示的页面排版效果,应该如下:
键名:1,键值:小明
...
答案:下载
5、while逻辑循环
当我们需要循环无限的执行下去,直到不再符合我们需要的条件时,才终止循环。这时候就可以使用到while
系列的循环语句
A、while()
while()
循环语句,是只要表达式一直为true
时,循环就会无限的执行下去,其表达式如下:
while (表达式为true时) {
要执行的代码块;
}
假设,我们要循环显示 1*9
的数字,示例代码如下:
<?php
$i = 1; // 先定义初始数
# 共循环9次
while ($i<=9) {
echo '1*' .$i. '=' .(1*$i). '<br/>';
# $i自增1,到10的时候循环表达式将为false,自动结束循环
$i++;
}
# 该循环的性能优化程度为O(n)
B、do{…}while()
do{...}while()和while()
循环语句的区别是在于,do{...}while()
语句会?先执行一次循环,然后再检测表达式是否为true
,才会进入下一次循环,其表达式如下:
do {
要执行的代码块;
} while (表达式为true时);
假设,我们要循环显示 1*9
的数字,示例代码如下:
<?php
$i = 1; // 先定义初始数
# 共循环9次
do {
echo '1*' .$i. '=' .(1*$i). '<br/>';
# $i自增1,到10的时候循环表达式将为false,自动结束循环
$i++;
} while ($i<=9);
# 该循环的性能优化程度为O(n)
老师提醒:不理解两种表达式的同学,可以尝试将上面的表达式直接修改为
false
,然后运行查看效果即可。
C、课后练习题
使用while()
语句,输出正9 X 9
乘法表结构。
显示的页面排版效果,应该如下:
1x1=1;
2x1=2; 2x2=4;
...
答案:下载