# 淘課計畫
## 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":"就是一些思路簡單處理小麻煩的題目"}