# 字串 String
## 簡介
- 在C++中是一個類別 (class)
- 雖然在 `#include<iostream>` 時就可以使用大部分的功能,但避免踩雷,使用時建議打上 `#include<string>`。
## 宣告方式
```cpp=
string str; //這是空字串
string str2 = "tree";
string str3(9, 'A'); //AAAAAAAAA
string str4[10]; //由字串組成,長度10的陣列
```
## 輸入/輸出方式
```cpp=
string str;
cin >> str; //只能輸入沒有空格的字串
getline(cin, str); //可以輸入一整行字串,有空格也行
cout << str; //輸出整個字串
cout << str[0]; //輸出字串第0個字元
```
## 常用運算子
### +
```cpp=
string str1 = "487", str2 = "63";
cout << str1 + str2; //48763
```
### 大小關係符號
```cpp=
string str1 = "487", str2 = "63", str3 = "48763", str4 = "487";
cout << (str1 > str2); //0
cout << (str1 < str3); //1
cout << (str2 >= str3); //1
cout << (str1 == str4); //1
cout << (str3 <= str4); //0
```
### [ ]
```cpp=
string str = "tree";
cout << str[0]; // 't'
cout << str[2]; // 'e'
```
## 常用函數
### length()
```cpp=
string str = "string";
cout << str.length(); //6
```
應用:
```cpp=
string str = "string";
for (size_t x = 0; x < str.length(); x++) cout << str[x] << ' ';
//s t r i n g
```
### find()
```cpp=
string str = "tree";
cout << str.find("t") << ' ' << str.find("e") << ' ' << str.find("p");
//0 2 18446744073709551615
```
說明:18446744073709551615 = string::npos,判斷時可以用
`if (str.find("p") == -1)` 即可。
### to_string()
```cpp=
int n = 48763;
string str;
str = to_string(n);
cout << str; // "48763"
```
### stoll()
```cpp=
int n;
string str = "871";
n = stoll(str);
cout << n; //871
```
### append()
```cpp=
string str, str2 = "kirito's ", str3 = "superstar", str4 = "stream";
str.append(str2); // "kirito's "
str.append(str3, 5, 4); // "star"
str.append(" burst ", 6); // " burst"
str.append(" str"); // " str"
str.append(1, 'e'); // "e"
str.append(str4.begin() + 4, str4.end()); // "am"
cout << str; // "kirito's star burst stream"
```
## 實用工具:ASCII 碼
### 簡介
ASCII 碼是一種編碼,可以用數字來表示字元,例如:65 為 'A' 這個字元,97 則是 'a',而 48 代表 '0' 這個字元。總共有 128 個編碼,而在C++中,這 128 個編碼是可以和其代表字元互相轉換的。
### 範例
```cpp=
int n = 67;
string str = "C8763";
cout << char(n) << ' ' << int(str[0]);//C 67
```
### 常用 ASCII 碼
- 48~57 分別為 '0' ~ '9'
- 65~90 分別為 'A' ~ 'Z'
- 97~122 分別為 'a' ~ 'z'
### 應用
在某些需要"分解位數"的題目中,使用 string 存整數搭配 ASCII 碼解題可能比用 int 存整數解題輕鬆。 例:[DDJ a175:水仙花數](http://203.64.191.163/ShowProblem?problemid=a175)
某些題目會要求把英文字母轉成數字並計算,這時也可以利用 ASCII 碼直接轉換。
例:[DDJ a251: 多元選修好難喔](http://203.64.191.163/ShowProblem?problemid=a251)
---
## 趣味題目:DD的哀傷
tree有個朋友,他的名字叫小DD。
小DD是110學測考爛卻還看Hololive的唯一的人。他身材矮胖,滿臉贅肉,眼袋下時常帶些黑影,一頭亂蓬蓬的油膩的頭髮。穿的雖然是運動服,可是又髒又破,似乎六年沒有補,也沒有洗。他對人說話,總是滿口 "草" (くさ,kusa),叫人半懂不懂的。因為他姓小,別人便從描紅紙上的「誰でも大好き」(Daredemo Daisuki) 這半懂不懂的話裡,替他取下一個綽號,叫作小DD。小DD一進留言區,所有正在看直播的人便都對著他笑,有的留言道:「小DD,你又在晚上熬夜了!」他不回覆,在留言區中留言「Rushia nice body boing boing pettan.」便排出7500新台幣。他們又故意地高聲嚷道:「你一定又花買飯錢斗內了!」小DD睜大眼睛說:「你怎麼這樣憑空汙人清白……」「什麼清白?我前天親眼見你在各個直播出現,投彩虹SC。」小DD便漲紅了臉,額上的青筋無法浮現,因為贅肉實在太多,爭辯道:「雙視角觀看不能算DD……雙視角!……單推 Hololive 的事,能算DD嗎?」接連便是難懂的話,什麼「華鯊公約」,什麼「Ahoy」之類,引得眾人都哄笑起來:留言區內外充滿了快活的空氣。
聽人家背地裡談論,小DD原來也當過單推,但終於沒有堅持,又一直加會員,於是越過越窮,弄到將要討飯了。他加會員的原則是:在有限的零用錢內,加越多越好。現在給你許多 Vtuber 的名字及其入會費,請問你知道他加了哪些 Vtuber會員嗎?
### 輸入說明:
第一行有一數 $M$,代表小DD的零用錢有多少。
第二行有一數 $N$,代表接下來會有幾位 Vtuber。
接下來 $N$ 行,每行有一字串 $S$ (不會有空白) 及一數 $K$,$S$ 代表 Vtuber 的名字,$K$ 代表其入會費。
### 輸出說明:
第一行輸出小DD加入了幾位 Vtuber 的會員。
第二行以字典序輸出他加入誰的會員,每個會員名間隔一空白,若有多種可能,請輸出:
1. 剩下零用錢較多,且
2. 名字較早被輸入的那組。
若可加入所有人的會員,請在第三行輸出"單推 Hololive 的事,能算DD嗎?"(不含引號)。
### 範例輸入:
```
300
5
Lamy 75
Aqua 100
Fubuki 100
Korone 100
Pekora 75
```
### 範例輸出:
```
3
Aqua Lamy Pekora
```