搭配green judge解題系統
Special thanks to 台中女中sagit老師 <(_ _)>
上一章:while迴圈
下一章:雜項:其他資料型態、函式庫、格式化輸出
回目錄:國立科學園區實驗中學C++程式語言自學講義
在上一單元
我們學會了while迴圈
再次複習一次while迴圈的使用時機
1.某段程式要一直重複執行
2.預先不知道要重複幾次,而是藉由判斷某個條件來決定該結束了沒
for迴圈則跟while迴圈非常相似
它的使用時機為
1.某段程式要一直重複執行
2.一開始就已知要重複幾次,所以只要判斷執行幾次了就知道該結束了沒
例如:
印出100個"Hello"
算出某個數字的某次方
算出某個數字的階乘…等等
由於在使用for迴圈時需要計算「迴圈執行幾次了」
所以需要另外使用一個變數來作為「計數器」
通常我們習慣將這個計數器的名稱取作 i 或 j 或 k
而這個計數器主要有三件任務
1.一開始先設定一個起始值
2.設一個檢查條件,每執行一次迴圈就檢查它還符合條件嗎(還符合才能繼續跑迴圈)
3.每執行一次迴圈就將計數器變動一下,例如加一
舉例來說,想要一個迴圈總共執行10次(i從0跑到9)的話
而這三件任務就分別被寫在for迴圈的三個格子裡
像是
int i; //宣告一個計數器
for ( i=0 ; i<10 ; i=i+1 ) //i從0開始;檢查是否還<10;每次加1
{
//要重複執行的程式
}
for迴圈的架構如下:
先寫一個for,並且在後面接上一個小括弧()
小括弧內用分號分成3格,分別寫上(計數器=初始值;檢查計數器是否符合條件;改變計數器的值)
接著一個大括號
裡面放入的就是要重複執行的程式
註:i=i+1
可以簡化成i++
i=i-1
也可以簡化成i--
因為for迴圈實在是太常寫到i=i+1
或i=i-1
了
為了方便,以下的範例程式皆會將它寫成i++
以及i--
【例題】
輸入一個n,輸出n個"Hello"
例如n為3時,輸出
Hello
Hello
Hello
本題的範例程式如下
int n, i;
cin>>n;
for(i=0;i<n;i++) //歸零;檢查到n次了沒;每次+1
{
cout<<"Hello"<<endl;
}
cout<<endl; //最後加個換行符號
這樣的程式其實等效於
int n, i;
cin>>n;
i=0; //歸零
while(i<n) //檢查到n次了沒
{
cout<<"Hello"<<endl;
i=i+1; //每次+1
}
cout<<endl;
for迴圈和while迴圈完全是可以等效轉換的
如果你忘記其中一種怎麼寫,改寫另一種也是可以的
但因為各自有適合的用途
所以還是建議在適合的情況下使用適合的迴圈
【學生練習題】
當然,計數器本身的值也可以拿來用
【例題】
輸入一個n,輸出從1到n的數字
這題可以寫成
int n, i;
cin>>n;
for(i=1;i<=n;i++){
cout<<i<<endl;
}
計數器不只可以順著數,當然也可以倒著數
【例題】
輸入一個n,輸出從n到1的數字
這題可以寫成
int n, i;
cin>>n;
for(i=n;i>=1;i--){
cout<<i<<" ";
}
【學生練習題】
- Green Judge a027: 倒數計時
注意:它是要印完一個數字空一格,不是換行喔
計數器的值除了可以被印出來
也可以拿來當成運算時的材料
例如每次都把答案加上或乘上目前計數器的值
注意:計數器的值可以拿來當成別的變數運算時的材料
但是最好不要在運算時改動到計數器的值
否則會造成邏輯混亂
【例題】
輸入一個n,輸出1至n的和
我們已經知道和的公式是
那麼就來試試看用迴圈算平方和是不是和用公式算的一模一樣
既然要算"和"
可以用一個變數來代表目前的和是多少
每次都將目前的和去加上目前計數器平方的值
int n, i, answer;
cin>>n;
answer = 0; //和一開始為0
for(i=1;i<=n;i++)
{
answer = answer+i; //加上計數器的值
}
cout<<answer<<endl;
//可以檢查是不是跟用公式算的一樣
if(answer == n*(n+1)/2)
cout<<"YA!"<<endl;
【例題】
輸入一個n,輸出n的階乘
既然要算階乘
可以先用一個變數來當成目前的積
然後每次都將目前的積乘上目前計數器的值
int n, i, answer;
cin>>n;
answer = 1; //積一開始為1 (為什麼?)
for(i=1;i<=n;i++){
answer = answer*i;
}
cout<<answer<<endl;
在以上的例子中
我們所用到的計數器,要不就是先歸零,要不就是從1開始
但其實它不管想從幾開始計都是可以的
【例題】
輸入n和m,輸出從n至m的所有整數(包含n與m)
這題可以讓計數器從n開始,到m結束
範例程式如下
int n,m,i;
cin>>n;
cin>>m;
for(i=n;i<=m;i++) //i從n開始;檢查i超過m了沒;i每次都+1
{
cout<<i<<endl;
}
【例題】
輸入兩個數字a, b
輸出的值
int a, b, i, ans;
cin >> a >> b;
ans=1;
for(i=a;i<=b;i++){
ans = ans*i;
}
cout << ans;
【學生練習題】
【例題】
輸入n和m,輸出從n至m的所有整數,兩兩整數間請用"~"來連接
例如n為2,m為5時,即輸出2~3~4~5
這個題目有一個小麻煩
就是每個數字前面都要加上一個飄號~
但唯獨第一個數字前面不能加
這邊提供其中一種解決方法:把第一個數字(n)獨立出來,而迴圈的計數器則從n+1開始
int n, m, i;
cin>>n;
cin>>m;
cout<<n; //先單獨印出第一個數字n
for(i=n+1;i<=m;i++) //計數器從n+1開始
{
cout<<"~"<<i; //印出飄號跟i
}
【學生練習題】
迴圈裡面還可以再做條件判斷
寫法就和一般的條件判斷相同
【例題】
輸入n,輸出n所有的因數
要判斷一個數字i是否為n的因數,可以判斷n除以i的餘數是否為零,即n%i==0
int n, i;
cin>>n;
for(i=1;i<=n;i++)
{
if(n%i==0)
cout<<i<<endl;
}
【學生練習題】
相同的程式也可以拿來判斷n是不是質數
可以再用一個變數來計算n有幾個因數
如果因數的數量為0,就可以確定n是質數 (1與n除外,因為一定有這兩個因數)
不過i的範圍要注意:
1.i要從2開始,因為1不用檢查
2.i超過根號n時就可以停了 (為什麼?)
不過根號n的寫法有點麻煩(下一章會教到)
因此你可以不要判斷
而是改成判斷
int n, i, cnt;
cin>>n;
cnt=0;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
cnt++;
}
if(cnt>0) cout<<"Not Prime"<<endl;
else cout<<"Prime"<<endl;
【學生練習題】
【例題】
輸入n和m,輸出n行的m個飄號
例如n為3,m為5時,輸出
~~~~~
~~~~~
~~~~~
我們已經知道印出一行m個飄號可以這樣寫
for(i=0;i<m;i++)
{
cout<<"~";
}
cout<<endl;
而現在需要將這樣的飄號印出n行來
也就是上面那一段程式要被執行n次才夠
因此可以把上面那一整段程式
再包進一個會被執行n次的迴圈裡
由於i已經被拿去當成剛才的迴圈的計數器了
為了避免衝突
我們要再宣告一個新的計數器:j
因此程式可以寫成
for(j=1;j<=n;j++)
{
for(i=1;i<=m;i++)
{
cout<<"~";
}
cout<<endl;
}
(不過通常i會放在外圈,j會放在內圈,通用習慣問題而已)
請記得,像這樣的「迴圈包迴圈」,並不是一個新的語法概念
就只是單純把一個迴圈寫在另一個迴圈裡而已
寫法規則都沒什麼差別
【學生練習題】
【例題】
輸入n,輸出高和寬為n的等腰直角三角形
例如n為4時,輸出
~
~~
~~~
~~~~
這題可以直接拿上一題的程式來用
唯一不一樣的地方是
內層迴圈的計數器,並非數到n,而是改成數到外層計數器的值
for(j=1;j<=n;j++)
{
for(i=1;i<=j;i++) //注意,這邊的檢查值改成i<=j囉
{
cout<<"~";
}
cout<<endl;
}
【學生練習題】
在迴圈內遇到break
時,不管怎樣,直接離開迴圈
【例題】
輸入n,輸出大於等於n的第一個5的倍數
(這例子舉得不好,但為了淺顯易懂,還是用這個例子吧)
計數器從n開始數到n+5 (因為這之間一定有5的倍數)
一旦遇到5的倍數並輸出它之後
迴圈就可以直接結束,不用再繼續往下跑了
因此可以使用break
for(i=n;i<=n+5;i++)
{
if(i%5==0){
cout << i <<endl;
break;
}
}
雖然i不一定有超過n+5
不過一旦它遇到break,還是會直接結束迴圈
在迴圈內遇到continue
時,不管怎樣,直接進入下一圈
【例題】
輸入n,輸出1至n之間所有5的倍數
這題你可以使用if來檢查i是否為5的倍數,如果是,則輸出
但你也可以不使用if,而利用continue來控制流程
比方說
在印出i之前,先檢查i是不是5的倍數
如果不是,那就直接continue進入下一輪迴圈
for(i=1;i<=n;i++)
{
if(i%5!=0)
continue;
cout<<i<<endl;
}
break和continue都不是絕對必要的語法
都可以用其他的寫法來代替
但是在適合的情況下若能善用break和continue
可以讓你寫程式更有效率、有邏輯
上一章:while迴圈
下一章:雜項:其他資料型態、函式庫、格式化輸出
回目錄:國立科學園區實驗中學C++程式語言自學講義