輸入含空白的字串
若輸入一個字串,使用 cin 會讀入到空白為止,但是,如果輸入是像這樣:
1 | dasd sakf jfsak fsakl |
那該怎麼讀入呢?
可以使用 4 次 cin,但如果空白個數不定,就糟糕了。
在這裡,介紹新的輸入字串方式:
1 | string s; |
getline(cin,字串名) 可以讓你輸入整行的含空白字串,直到讀入換行符號’\n’為止。
於是可以這樣輸入:
1 | string s; |
getline其實也可以指定讀到特定字元為止,附上詳細教學連結。
注意,若使用char[]宣告字串,語法不同,需這樣寫:
1 | char s[105]; |
這份講義之後的code,會全數使用string。
getline 與 cin 混用時
輸入一個整數,然後輸入一個含空白的字串,要怎麼寫呢?
直覺的想法可能是:
1 | int n; |
然而,輸入若是:
1 | 3 |
輸出的結果卻是:
1 | 3 |
為什麼會這樣呢?
還記得 cin 一個整數時的運作原理嗎?一直讀入直到遇見不是整數的字元。
那 getline 的運作原理是,讀入直到遇見換行字元。
發現了嗎?若輸入的檔案是一整數、換行、一字串,cin 遇到換行停在換行的位置,這時使用 getline,就不幸的吃到那個換行後結束了。因此讀到的字串什麼都沒有。
要怎麼解決這個問題呢?最簡單的方法是再呼叫一次getline:
1 | int n; |
然而,這麼寫會影響程式可讀性。因此,可以用 cin.ignore() 來表示我要忽略下一個字元:
1 | int n; |
這樣一來,換行字元就成功被跳過了!
cin/cout 加速
cin/cout 其實是一個速度很慢的功能,原因請點連結。
而速度於程式解題競賽中是相當重要的一部分,因此,我們要想辦法讓 cin/cout 加速。
加速的方法有以下兩種:
使用輸入優化
也就是在上方連結可看到的:
1
ios::sync_with_stdio(0), cin.tie(0);
在main函式的開頭,打上這句,cin就加速許多,原因一樣在上方那篇。
因此看起來會像這樣:
1
2
3
4
5
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0);
}避免使用 endl
endl其實是由,’\n’與flush組成,flush會使目前輸出的所有東西立刻顯現至螢幕上,但作為代價,其速度並不高。因此,細心的讀者可以注意到,本講義中,所有需要換行的場合,都是使用’\n’進行換行
以上兩點,需同時使用,才能快速進行高達百萬級的輸入輸出。
若只使用第一點,不使用第二點,則在輸出時仍然會因為flush過慢拖累整體執行效率。
若只使用第二點,雖然輸出時不會 flush,但 cin 時預設也會 flush,因此依然很慢。
雖然目前可能還不需要用到,但是在TLE時,請務必想想:是不是輸入太慢造成的問題?
練習
355這題會用到一點迴圈的概念,可以先往後讀,之後再回來。
AC Code
1 | // TOJ 5 |
1 | // TOJ 355 |