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>