--- title: 迴圈 tage: c++程式設計實習 --- :::success 需要重複做的事情,都可以利用迴圈處理. ::: # for迴圈 :::success <font color='red'>**當已經知道要執行的次數**</font> ::: 1. 語法 ```cpp=1 font(初值設定;條件運算式;更新{ 重覆要執行的動作 } ‵‵‵ - 初值設定:只會在第一次時執行 - 條件運算式:當結果為1(true)時才會執行回圈內的事情,反之.結束迴圈執行 - 更新運算式:條件運算式的程式內的某些變數 2. 範例: $1+2\sim+100=$ ```cpp=1 #include<iostream> using namespace std; int main() { int total=0; for(int i=1 ;<=100; i+1){ total+=1; } printf("1+2+...+100=%d\n",total); return 0; } ‵‵‵ 3. 練習一:請計算$1\SIM 100$的偶數和 ```cppy= #include <iostream> using namespace std; int main() { //處存總和 int total=0; //1~100 for(int i=1;i<=100;i++) if(i%2==0) total+=1; } printf("1~100偶數和%d\n",total); total=0; for(int i=2; i<=100; i+2){ total += i; } printf("1~100偶數和%d\n",total); return 0; } ``` 4. 練習二:請顯示$1\sim 100$的能被3與9整除的數字 ```cpp= #include <iostream> using namespace std; int main() { for(int i=1;i<=100;i++){ if(i%3==0 && i%7==0) printf("%d",i); } return 0; } ``` 5. 自我練習:計算$123\sim9999中的5得倍數和$ :::success 當迴圈不確定要執行幾次的時候使用 ::: 1. 語法: ```cpp=1 初值設定: while(條件運算式){ 重覆要執行的事 更新運算式 } ``` - 初值設定 條件運算式 更新運算式:與for迴圈 說明相同 - 2. 範例:$1+2=\sim+100$ ```cpp=1 #inclube<iostream> ``` 3. 練習一:設計重複計算BMI的程式,使用者輸入體重(kg) 身高(cm) 計算BMI 當按下y或Y時繼續計算.BMI參考 https://zh.wikipedia.org/wiki/%E8%BA%AB%E9%AB%94%E8%B3%AA%E9%87%8F%E6%8C%87%E6%95%B8 ```cpp=1 #include <iostream> using namespace std; int main() { int total=0; int i=1; while(i<=100){ total+=i;//total=total+i i+=1; } printf("%d\n,total"); return 0; } ```cpp>>go #include <iostream> #include <cstdio> using namespace std; int main() { //儲存使用者輸入的身高與體重 float h,w; //儲存使用者輸入的字元 char go='y'; //執行while迴圈來計算BMI while(go=='y'||go=='y'){ //讓使用者輸入身高與體重 scanf("%f%f",&h, &w);//cin>>h>>w; //身高由cm變為m h/=100; //計算BMI float bmi=w/(h*h); //輸出 BMI printf("BMI=%.2f\n",bmi); //詢問是否繼續 printf("要繼續請輸入(y or y):"); //sacnf("%c",&go); cin>>go; } return 0; } ``` 4. 自主練習:3n+1問題 - 對於任意大於$1%$的自然數$N% 諾$n$為奇數 則將$n$變為$3n+1$ 否則變為$n$的一半 經過諾干次這樣的變換 一定使$n%變為$1$.例如$3\to 10\to 5\to 16\to 8\to 4\to 2\to 1$. - 輸入$n$ 輸出變出的次數 $n%<10^9$ - 輸出範例:3 - 輸出範例:7 ```cpp=1 //#include <iostream> #include<cstdio> using namespace std; int main() { int n; scanf("%d,&n"); int counts=0; while(n>1){ if(n%2)n=n*3+1; else n /=2; counts++; printf("time %d: %d\n",counts, n); } printf("%d\n",counts); return 0; } ``` - 當輸入9999999時只會執行一次 請說明原因. # do...while迴圈 :::success 此迴圈一定會最少執行一次 其餘與while相同 ::: 1. 語法: ```cpp=1 初值設定; do{ 重複要得執行 更新運算式 }while(條件運算式); ``` 2. 範例: $1+2+\sim+100=$ ```cpp=1 #include <iostream> using namespace std; int main() { int total=0; int i = 1; do{ total+=i; i++; }while(i<=100); printf("%d\n",total); return 0; } ``` # 巢狀迴圈 :::success - 巢狀迴圈(Nested Loop):回圈內還有其他迴圈 - 二層:第一層內還有一層 ::: 1. 產生一個$9\times 9$乘法表 ```cpp=1 ``` # 無窮迴圈 :::success 永遠不會停止的迴圈 嵌入式系統(embedd)必須架構於無窮迴圈下. ::: 1. 使用for:for(;;) 2. 使用while:while(1) while(-100) while(非0的數字) # break 敘述 :::success 跳離break最近的\}(離開最近的迴圈),移到\}的下一行敘述開始執行 ::: 1. 利用break,計算$1\sim100中的總和 #include <iostream> using namespace std; int main() { int total=0; for(int i=1;i<100;i++){ if(i>50){ break; } total+=i; } printf("%d\n",total); return 0; } # continue :::success 遇到contiune就執行最近的迴圈的開頭(回到迴圈的開始位置),繼續迴圈 ::: 1. 利用contiune計算$1\sim100$中的偶數和. ```cpp=1 #include <iostream> using namespace std; int main() { int total=0; for(int i=1; i<=100; i++){ if(i%2) continue; total+ = i; } printf("%d\n",total); return 0; } ``` # 近似計算 ${pi\over 4}=1-{1\over 3}+{1\over 5}-{1\over 7}\dots$,直到最後一項小於$10^{-6}$ ```cpp #include <iostream> using namespace std; int main() { double sum=0.0, term; do{ term=1./(2*i+1); if(i&2) sum-=term; else sum+=term; i++; }while(term>1e-6); printf("%.6f\tpi=%.5f\n",sum); return 0; } ``` # 階層之和 輸入$n$,計算$S=1!+2! + 3! +\dots + n!$的末$6$位(不含前導$0$) # 水仙花數(daffodil) 輸出 $100\sim 999$ 中的所有水仙花數。若$3$位數 $ABC$ 滿足 $ABC=A^3+B^3+C^3$,則稱水仙花數,例如 $153=1^3+5^3+3^3$,所以$153$是水仙花數。 #include <iostream> ```cpp using namespace std; int main() { for(int i=100;i<=999;i++){ int a = i/100; //百位數:去除 i後面的2位數 int b = i/10%10; //十位數: int c = i%100; //個位數: if(i == (a*a*a+b*b*b+c*c*c)) cout<<i<<"\n"; } return 0; } ``` # 韓信點兵(hanxin) 相傳韓信才智過人,從不直接清點自己軍隊的人數,只要讓士兵先後以三人一排、五人一排、七人一排地變換隊形,而他每次只瞄一眼隊伍的排尾就知道總人數了。 輸入包含多組資料,每組資料包含$3$個非負整數$a, b, c$,表示每種隊形排尾的人數$(a<3、 b<5 、 c<7)$。 輸出總人數的最小值(或報告無解)。已知總人數不小於$10$,不超過$100$。 範例輸入:(使用重新導向或檔案存取方式) $2\ 1\ 6$ $2\ 1\ 3$ 範例輸出: case $1:\ 41$ case $2$: No answer # 分數化小數(decimal) 輸入正整數$a、 b、 c$,輸出 $a/b$ 的小數形式,精確到小數點後$c$位。$a,b≤10^6、c ≤ 100$。輸入包 含多組資料,結束標記為 $a=b=c=0$。 範例輸入:(使用重新導向或檔案存取方式) $1\ 6\ 4$ $0\ 0\ 0$ 範例輸出: $case\ 1:\ 0.1667$ #include <iostream> #define LOCSAL using namespace std; int main() { #ifdef LOCAL freopen("data.in","r", studin); freopen("data.in","r", studin); #endif // LOCAL ```cpp int a,b,c,kase=0; //1.不斷讓使用者輸入a,b,c的值 //2.當a=b=c時,結束輸入程式 while(cin>>a>>b>>c&&a||b||c){ //顯示整數部分 cout<<"case"<<(++kase)<<":"<<a/b<<"."; //先取得a/b的餘數 a%=b; //計算小數點後 while(c--){ //小數點後被除數每一位*10 a*=10; //目前這位數的商 int q=a/b; //如果已經在小數第c位,判斷c+1位是否大於5 //四捨五入用 if(c==0&&(a%b)*10/b>=5) q++; //四捨五入 cout<<q; //下一位被除數0 a%=b; } cout<<"\n"; } return 0; ``` } # 排列(permutation) ```cpp 用$1,2,3,\dots,9$組成$3$個三位數 $abc、def 和 ghi$,每個數字恰好使用一次,要求 $abc: def: ghi=1:2:3$。 按照「$abc\ def\ ghi$」的格式輸出所有解,每行一個解。 #include <iostream> #define LOCSAL using namespace std; int main() { #ifdef LOCAL freopen("data.in","r", studin); freopen("data.in","r", studin); #endif // LOCAL int n, m,kase=0; while(cin>>n>>m&& (n)(m)){ double sum=0 for(int i=n; i<m; i++){ //sum+-1./i/i; } printf("case %d: %.5f\n",++kase,sum); } return 0; } ``` # 子序列的和(subsequence) 輸入兩個正整數$n<m<10^6$,輸出$1/𝑛^2 +1/(𝑛+1)^2 +\dots +1/𝑚^2$ ,保留5位小數。輸入包含多組資料,結束標記為 $n=m=0$。 範例輸入:(使用重新導向或檔案存取方式) $2\ 4$ $65536\ 655360$ $0\ 0$ 範例輸出: $case\ 1:\ 0.42361$ $case\ 2:\ 0.00001$ ```cpp #include <iostream> #define LOCSAL using namespace std; int main() { #ifdef LOCAL freopen("data.in","r", studin); freopen("data.in","r", studin); #endif // LOCAL int n, m,kase=0; while(cin>>n>>m&& (n)(m)){ double sum=0 for(int i=n; i<m; i++){ //sum+-1./i/i; } printf("case %d: %.5f\n",++kase,sum); } return 0; ```