因為不知道總共會有幾筆資料所以必須透過一些小技巧來進行
以下大約列出幾種常見的測試資料輸入範例
會以 UVa 的題目做為例題,但是因為這篇只討論輸入部份所以不會完整解題
Case 1. 多筆輸入直到檔案結尾
Example: UVa 10494 If We Were a Child Again
Partial code:
int a, b; char math; // This is a solution. while( scanf( "%d %c %d", &a, &math, &b ) != EOF ) { /* Some code here. */ } //This one is also ok. while( scanf( "%d %c %d", &a, &math, &b ) == 3 ) { /* Some code here. */ }每呼叫一次 scanf() 都會產生兩種效果:
第一個效果是會讓使用者的輸入送進指定的變數中,
而第二個效果是在接收完使用者輸入之後,
scanf() 會將自身這串替換成一個數字 (此即 scanf() 的返回值,若不知道函數的返回值是什麼,就想像這整段會變成一個數字好了)
因為這裡 scanf 共接收了三個來自使用者的輸入( a, math, b 共3個變數),所以 scanf() 會變成3
若為 scanf( "%d", &a ); 的話,那麼它將會變成 1,因為它只接收一個變數
以此例來講的話,在輸入完3個變數之後,這句將變成
//上面那種做法 while( 3 != EOF ) ...... //這個 3 是 scanf 變成的 //下面的做法 while( 3 == 3 ) ......此時條件成立,故迴圈將繼續進行
當 scanf() 接收到檔案結尾的時候,它會變成 EOF,程式實際上將變成
//上面那種做法 while( EOF != EOF ) ...... //下面的做法 while( EOF == 3 ) ......這時候條件不成立,迴圈將結束而跳出
Case 2. 給定資料數,再輸入該數量的資料
Example: UVa 11547 Automatic Answer
Partial code:
int t, i, input; // i 只是一個計數器 scanf( "%d", &t ); // t 代表接下來有幾筆測試資料 // This is a solution. while( t-- ) { scanf( "%d", &input ); } //實際上還有許多 code 要打,當然不只這些 // Here's another solution. Please choose only 1 solution for this. // This solution is longer, but more understandable. for( i = 0; i < t; ++i ) { scanf( "%d", &input ); }
Case 3. 多筆資料,以 0 表示輸入結束
Example: UVa 10550 Combination Lock
Partial code:
int a, b, c, d; //一次有四個數字進來,所以弄出 abcd while( scanf( "%d %d %d %d", &a, &b, &c, &d ) && ( a+b+c+d ) ) { /* Some code here. */ }
這麼用法是因為 while 迴圈裡出現了 && 運算符,
scanf() 將會變成 4 (見 Case 1 說明), 而非 0 的數在 C 裡面會視為 True 並繼續進行 && 後的條件判斷
又提及,非 0 的數為 True,則若為 0 時就是 False,
當最後一筆四個 0 出現時, a+b+c+d = 0,會視為 False (不成立),
因而跳出 while 迴圈而結束
Case 4. 多筆輸入,以某一特定文字、數字、字元做為結束
Example 1: UVa 12577 Hajj-e-Akbar
Partial code:
char input[ 20 ]; while( scanf( "%s", input ) && input[ 0 ] != '*' ) { /* Some code here. */ }
當最後一筆輸入 * 的時候,會使得 && 後面的條件判斷不成立(因為 input[ 0 ] 為 *)
所以會結束迴圈
Example 2: UVa 12468 Zapping
Partial code:
int a, b; while( scanf( "%d %d", &a, &b ) && ( a != -1 || b != -1 ) ) { /* Some code here. */ }
這裡題目約定了兩個 -1 代表輸入的結束,
所以將它們寫到 && 的後面進行判斷(注意到我們可以不必用 EOF 來判斷迴圈的結束,所以可以不必寫 != EOF 來節省程式碼長度)
當兩個數字都是 -1 時, && 後的條件都會不成立所以變成 False 而跳離迴圈
又因為 || 的運算優先序比 && 低,所以 || 必須括號起來一起運算
沒有留言:
張貼留言