# 淘課計畫 ## week 4 ---- ## 本周主題是字串處理 ~~就是一些思路簡單處理小麻煩的題目~~ ---- ## 題目連結 [vjudge](https://vjudge.net/contest/623637) --- ## [problem A][1] [1]: https://zerojudge.tw/ShowProblem?problemid=d235 ---- #### 題意 本題是多筆輸入 每行給你一個 $N$ 位數 ($1$ < = $N$ < = $1000$),請你判斷它是不是11的倍數。 ---- #### 作法 國中我們都學過判斷 $11$ 倍數的方法 S~1~是奇數位的數總和,S~2~是偶數位的數總和 ( | S~1~ - S~2~ | % $11$ ) = 0 就是 $11$ 倍數 ---- #### 作法 注意到這題 $N$ 的範圍 $1$ < = $N$ < = $1000$ 遠遠超出 unsigned long long 可存放的範圍 所以要用字串處理 記得判斷結束輸入 --- ## [problem B][1] [1]: https://zerojudge.tw/ShowProblem?problemid=c007 ---- #### 題意 給一段文字當中有數個 " 將左邊改為 `` 右邊改為 '' Note:`` ---- #### 作法 輸入一字串後逐一掃過去 可以用一個變數紀錄當前是左 " 或右 " ---- #### 作法 注意 : 整題為一個段落,不是一句一句分開算 ~~這到底是什麼爛題目~~ --- ## [problem C][1] [1]: https://zerojudge.tw/ShowProblem?problemid=c014 ---- #### 題意 給兩個十位數以下的數 $A , B$ 求 $A + B$ 有幾次進位 ---- #### 作法1 用整數處理 這題因為 $A , B$ 沒有超過 $int$ 存取範圍 所以可以用整數輸入再從個位數開始往高位計算 ---- #### 參考code ```cpp= bool carry = false; while (a > 0 || b > 0) { int sum = a % 10 + b % 10 + carry; carry = false; if (sum >= 10) { result++; carry = true; } a /= 10; b /= 10; } ``` ---- #### 作法2 用字串處理 原理跟做法1差不多,差別在於用字串處理 可以存放超過 $10$ 位數以上的大數 ---- 把第三行改成這樣 ```cpp int sum = a[i]-'0' % 10 + b[i]-'0' % 10 + carry; ``` --- ## [problem D][1] [1]: https://zerojudge.tw/ShowProblem?problemid=c813 ---- #### 題意 給一 $W$ (1 < = $W$ < = 2*10^9^) 位正整數 $n$ 重複把每一位數相加,求只剩一位數時的結果 ---- #### 作法 跟題 $A$ 狀況一樣 , $W$ 的範圍 $1$ < = $W$ < = 2*10^9^ 遠遠超出 unsigned long long 可存放的範圍 :arrow_right:用字串處理 ---- #### 作法 本題可以用遞迴或迴圈的方式寫 終止條件是當 $n$ < $10$ ---- 迴圈參考寫法 :::spoiler ```cpp= int sum; string str; do{ sum=0; for(int i=0;i<str.size();i++){ sum+=s[i]-'0'; } str = to_string(sum); }while(sum>10) ``` ---- 遞迴參考寫法 :::spoiler ```cpp= string f(string s){ if(s.size()==1){ return s; } int sum=0; for(int i=0;i<s.size();i++){ sum+=s[i]-'0'; } s = to_string(sum); return f(s); } ``` --- ## [problem E][1] [1]:https://zerojudge.tw/ShowProblem?problemid=c045 ---- #### 題意 將文字往順時針方向旋轉90度輸出 包括所有空白、標點符號 ---- #### 作法 (前置處理) 因為每一行都有空白 要用 getline 輸入 可以順便紀錄最寬一行的長度 ---- 參考程式碼 :::spoiler ```cpp= vector<string> vec; int border = 0; string str; while (getline(cin, str)) { vec.push_back(str); border = max(border, str.size()); } ``` ---- #### 作法 用雙迴圈一排一排輸出 如果字串長度不夠就補空白 ---- 參考程式碼 :::spoiler ```cpp= for (int i = 0; i < border; i++) { for (int j = vec.size()-1; j >= 0; j--) { if (vec[j].size() > i) { cout << vec[j][i]; } else { cout << " "; } } cout << '\n'; } ``` --- ## [problem F][1] [1]:https://zerojudge.tw/ShowProblem?problemid=e507 ---- #### 題意 多行輸入,連續的兩行為一組 按照字典序輸出兩個字串中 都有出現的字母與它們的數量 ---- #### 作法 用兩個陣列分別紀錄兩個字串中的字母數量 再取較小數量的輸出 ---- 參考程式碼 :::spoiler ```cpp= string a, b; for (int i = 0; i < a.size(); i++) arr[(a[i] - 'a')]++; for (int i = 0; i < b.size(); i++) brr[(b[i] - 'a')]++; for (int i = 0; i < 26; i++) crr[i] = min(arr[i], brr[i]); for (int i = 0; i < 26; i++) { for (int j = 0; j < crr[i]; j++) { cout << (char)(i + 'a'); } } ``` --- ## 字串串流處理 String Stream C++ 中用來處理字串的 stream。 - 字串切割 - 型別轉換 ---- ### 宣告與初始化 ```cpp= #include <iostream> #include <sstream> int main() { std::stringstream ss; ss.clear(), ss.str(""); } ``` ---- ### 對字串串流輸入 ```cpp= #include <iostream> #include <sstream> int main() { std::stringstream ss; ss.clear(), ss.str(""); std::string str; getline(std::cin, str); ss << str; } ``` ---- ### 對字串串流輸出 - 字串串流允許型別準換 ```cpp= std::stringstream ss; ss.clear(), ss.str(""); std::string str; getline(std::cin, str); ss << str; std::vector<int> vec; int tmp; while (ss >> tmp) { vec.push_back(tmp); } ``` ---- ### 記憶體管理 0 #### 有一說法 stringstream 有點肥,盡可能不要重複宣告。 ---- ### 記憶體管理 1 直接宣告在全域,快速省時間 ```cpp= #include <iostream> #include <sstream> using namespace std; stringstream ss; int main() { } ``` ---- ### 記憶體管理 2 宣告在區域,傳參考,安全又專業。 ```cpp= #include <iostream> #include <sstream> #include <vector> using namespace std; vector<int> input(stringstream& ss) { vector<int> in; ss.clear(), ss.str(""); string str; getline(cin, str); ss << str; int tmp; while (ss >> tmp) { in.push_back(tmp); } return in; } int main() { stringstream ss; vector<int> nums = input(ss); for (int num : nums) { cout << num << endl; } } ``` ---- ### 聽說這學期程設都沒有作業 (已經有照難度排好,請安心服用) - [d098. Stringstream運用練習(C++)](https://zerojudge.tw/ShowProblem?problemid=d098) - [d018. 字串讀取練習](https://zerojudge.tw/ShowProblem?problemid=d018) - [a271. 彩色蘿蔔](https://zerojudge.tw/ShowProblem?problemid=a271) - [a017. 五則運算](https://zerojudge.tw/ShowProblem?problemid=a017)
{"title":"淘課計畫","contributors":"[{\"id\":\"bffaf279-8d3a-496c-8b77-a0c84044345e\",\"add\":3945,\"del\":816},{\"id\":\"28c595c6-c7e6-4c5f-b0f6-532706b04770\",\"add\":1662,\"del\":15}]","description":"就是一些思路簡單處理小麻煩的題目"}
    104 views