5.1 循环结构的概念
先来看看生活中的一些场景;
(1)食堂阿姨打菜:接过顾客的餐盘→询问菜品→打菜→递回餐盘,重复以上过程,直到所有顾客的菜都打完。
(2)快递员送快递:查看送件地址→赶往目的地→电话告知收件人→收件人签字→交快递件,重复以上过程,直到所有需要送的快递都处理完。
(3)作业流程:布置作业→查看作业→编写作业→完成作业→把作业发送到邮箱,重复以上过程,直到作业发送到邮箱。
以上场景都有一个共同的特点:有条件地重复做一件事,每一次做的事情不同但类似。
程序是为了解决实际问题,实际问题中存在着重复动作,那么程序中也应该有相应的描述,这就是循环。
案例:
<script>
/*计算1+2+3+……+10*/
/*方案一*/
var sum1 = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;
/*方案二*/
var sum2 = 0;
sum2 += 1;
sum2 += 2;
sum2 += 3;
sum2 += 4;
sum2 += 5;
sum2 += 6;
sum2 += 7;
sum2 += 8;
sum2 += 9;
sum2 += 10;
</script>
但是这两种方案的描述方式都不太理想,如果是要加到10000,那你就够呛了,不知道要输到什么时候。
注意观察案例二会发现,它是重复地做一件事(将一个数加到sum2中),每一次做的都不同但类似。
我们希望能找到一种更简便的方法
<script>
/*方案三*/
var sum3 = 0;
var n = 1;
while(n <= 10){
sum3 += n;
n++;
}
alert(sum3);
</script>
方案三表达的含义和方案二一样,但是表达式要好得多,比如加到10000,只需要把条件n<=10改成n<=10000,是不是方便很多。
5.2 while循环
While是表示“当……则……”,也就是当某个条件成立时,则一直重复做。
do{语句}while(条件)先执行后判断
<script>
var daffodil = 100;
while (daffodil <=999) {
var num100 = Math.floor((daffodil % 1000) / 100);
var num10 = Math.floor((daffodil % 100) / 10);
var num1 = Math.floor(daffodil % 10);
var sum = Math.pow(num100, 3) + Math.pow(num10, 3) + Math.pow(num1, 3);
if (sum == daffodil){
alert(daffodil + "是水仙花数");
}
daffodil ++;
}
</script>
案例:GDP预测
<script>
var year = 2009;
var gdp_usa = 142562.75;
var gdp_chn = 49089.82;
do{
gdp_usa *= 1 + 0.02;
gdp_chn *= 1 + 0.08;
year ++;
}while(gdp_usa > gdp_chn);
alert(year + "年,中国" +gdp_chn + "将超过美国" +gdp_usa);
</script>
用这个方法是不是方便很多,而且也清晰了不少。
循环的套路
(1)初始状态;
(2)循环条件;
(3)循环体(要重复做的事情);
(4)为下一次循环做准备();
如何写循环程序需要先回答四个问题:
(1)初始状态是怎样的?
(2)重复做的条件是什么?
(3)重复做什么?
(4)怎么过渡到下一次循环?
5.3 for循环
<script>
for (var daffodil=100; daffodil <=999; daffodil++) {
var num100 = Math.floor((daffodil % 1000) / 100);
var num10 = Math.floor((daffodil % 100) / 10);
var num1 = Math.floor(daffodil % 10);
var sum = Math.pow(num100, 3) + Math.pow(num10, 3) + Math.pow(num1, 3);
if (sum == daffodil){
alert(daffodil + "是水仙花数");
}
}
</script>
5.4 循环辅助语句
break:跳出所在的switch或者循环体。
案例:素数判断
<script>
/*
* 素数就是除了1和本身之外再没有其它因子
* (1)提示并接收待判定的数的输入
* (2)在【2,n-1】之间去寻找因子
* (3)如果找到则设置找到标志,并提前结束
* (4)根据标志输出相应的结果
* */
/*var n = Number(prompt("请输入一个自然数"));
var found = false;//找到因子的标记
// for (var i = 2; i <= n - 1; i++) {
for (var i = 2; i <= n / 2; i++) {
if (n % i == 0) {
found = true;
break;//找到提前结束
}
}
alert(found ? "不是素数" : "是素数");*/
var n = Number(prompt("请输入一个自然数"));
var m = Math.ceil(Math.sqrt(n));//根据数学相关的定理,判断范围可进一步缩小至[2,sprt(n)]
var found = false;//找到因子的标记
for (var i = 2; i <= m ; i++) {
if (n % i == 0) {
found = true;
break;//找到提前结束
}
}
alert(found ? "不是素数" : "是素数");
</script>
continue:结束本次循环,开启下一次循环。
案例:对100以内即不是3的倍数也不是5的倍数求和
常规思路:对满足条件的数累加(思路一)
另一种思路:不满足条件就放过(思路二)
<script>
/*
* 对100以内即不是3的倍数也不是5的倍数求和
* 思路一:
* (1)对[1,100]范围的数每个数进行判断
* (2)如果满足条件就累加
* (3)输出和
* */
/* var sum = 0;
for (var n = 1; n <= 100; n++) {
if (n % 3 != 0 && n % 5 != 0){//不是3的倍数也不是5的倍数
sum += n;
}
}
alert(sum);*/
/*
* 思路二:
* (1)对[1,100]范围的数每个数进行判断
* (2)如果不满足条件就放过
* (3)累加
* (4)输出结果
* */
var sum = 0;
for (var n = 1; n <= 100; n++) {
if (n % 3 == 0 && n % 5 == 0){
continue;//结束本次循环
}
sum += n;
}
alert(sum);
</script>
思路二的好处是:结构清晰
也就是我们在进行数据处理之前,先把各个不符合条件排除掉,然后再处理满足条件的情况(这个一般是程序的主体)
如下伪代码
for(……){
if(条件一){
If(条件2){
主体代码(可能代码较多)
} else{
alert(“错误提示2
}
}else{
alert(“错误提示1
}
}
换一个思路来描述,如下伪代码
for(……){
if(!条件一){
alert(“错误提示1”);
continue;
}
if(!条件二){
alert(“错误提示2”);
continue;
}
循环体主体代码
}
5.5 循环嵌套
大括号里可以写任意语句
因为一件事情的内容需要重复做,而且这个事情要反复做,所以有循环的嵌套。
一般有行数有列数并且两者之间存在关系的时候用循环的嵌套。
两者没有直接关系
比如直角三角形的输出
<script>
for (var i = 1; i <= 3; i++) {
for (var j = 1; j < i + 1; j++) {
document.write("*");
}
document.write("</br>");
}
</script>
等腰三角形
<script>
//定义等腰三角形的行数
var num = 10;
//每一行的空格数为总数减去当前是第几行
//循环条件行数小于等于10
for (var i = 1; i <= num; i++) {
for (var j = num - i; j > 0; j--) {
document.write("_");
}
for (var k = 1; k <= i * 2 - 1; k++) {//每一行的星星个数为当前行*2-1
document.write("*");
}
document.write("</br>");
}
</script>