C++ 文字列操作まとめ

# C++の文字列操作のメモ
コーディング面接に向けて基本的な文字列操作を覚えておいた方がいいと言われたので自分用としてここにメモしときます。

## 部分文字列を取り出す
下の２通りの方法で部分文字列を取り出すことができる。
一つ目はstart番目の文字からnumberで指定した数だけ取り出され、二つ目ではstart番目の文字から最後の文字までが取り出される。
文字列の最後から数えて何番目かを指定して部分文字列を得るような関数はないので自分で実装する必要がある。

```
s.substr(start,number);
s.substr(start);
```
具体的には下のような結果になる。

```substr.cpp
    string s = "abcdefg";
    cout<<s.substr(0)<<endl;   //abcdefg
    cout<<s.substr(6)<<endl;   //g
    cout<<s.substr(1,3)<<endl; //bcd
    cout<<s.substr(0,7)<<endl; //abcdefg
```

## 文字の判定
文字が数字かアルファベットか、小文字か大文字かを判定する関数は下の通り。

```
isalnum(char)
isalpha(char)
isdigit(char)
islower(char)
isupper(char)
```

具体的には下のようにstring sのそれぞれの文字について上の4つの関数を利用できる。

```judgment.cpp
#include<iostream>
#include <ctype.h>
string s = "21aA"
cout << "isalnum: "<<  isalnum(s[0]) << endl;// 2 -> True  英数字か
cout << "isalnum: "<<  isalnum(s[2]) << endl;// a -> True  英数字か
cout << "isalpha: "<<  isalpha(s[0]) << endl;// 2 -> False アルファベットか
cout << "isdigit: "<<  isdigit(s[1]) << endl;// 1 -> True  数字か　
cout << "islower: "<<  islower(s[2]) << endl;// a -> True  小文字か
cout << "isupper: "<<  isupper(s[3]) << endl;// A -> True  大文字か
```

## 文字列を小文字、または大文字に変換
### 一文字だけ変換するとき
`std::tolower` または`std::toupper`で変換できる。

```capital_small.cpp
#include <iostream>
using namespace std;

int main(){
	char capital = 'A';
	char capital_to_small = tolower(capital);
	char small = 'a';
	char small_to_capital = toupper(small);
	cout<<"capital->small:"<<capital_to_small<<endl; // a
	cout<<"small->capital:"<<small_to_capital<<endl; // A
  return 0;
}
```

### 文字列全体を変換するとき
`std::tranform`と`std::tolower` または`std::toupper`で変換できる。
transformの引数は下のようになっている。

```
transform(変換する要素の先頭,変換する要素の終端,コピー先の先頭,関数オブジェクト)
```

下が使用例です。sを大文字にしたものをnew_sに入れるために最初の`transform`の第三引数を`new_s.begin()`としている。

```string_version.cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main(){
    string s = "ABcd";
    string new_s = s;
    transform(s.begin(), s.end(), new_s.begin(), ::toupper);
    cout<<"toupper:"<<new_s<<endl; // ABCD

    transform(s.begin(), s.end(), s.begin(), ::tolower);
    cout<<"tolower:"<<s<<endl; // abcd
    return 0; 
}
```

ここで文字列の一部分だけを変えるときは下のように場所を指定する。`transform`の第一引数から第二引数の一つ手前までが操作対象になる。第三引数はコピー先の先頭なので第一引数と同じ値にする。
下の例では2文字目から3文字目から小文字に変換される。

```
transform(s.begin()+1, s.begin()+3, s.begin()+1, ::tolower);
```
## split関数の実装
## sort, reverse
文字列内の文字をソートできる。

```sort_reverse.cpp
string s = "ACDB";
sort(s.begin(),s.end());//ABCD
sort(s.begin(),s.end(),greater<char>());//DCBA
reverse(s.begin(),s.end());//ABCD
```

## 文字列S内に文字列Tが含まれているか確認する
`find`か`rfind`を使いる。どちらも見つかればその位置を返し、見つからなければ`std::string::npos(= -1)`を返す。
`find`は文字列の先頭に最も近い位置を返し`rfind`は文字列の末尾側の位置を返す。

```findTfromS.cpp
std::string S = "abcabc",T = "abc";
std::string::size_type pos

pos = S.find(T);
if(pos!=std::string::npos){
   td::cout<<pos<<std::endl;  // 0
}

pos = S.rfind(T);
if(pos!=std::string::npos){
   td::cout<<pos<<std::endl;  // 3
}

```

## replace
## 文字列内の文字を消去
### erase
指定したイテレータの文字を消去。
複数消去したい時は2番目の例のようにすると[first,end)の文字が消去される。

```cpp
string str = "abcdefg";
str.erase(str.begin()+2);//abdfg
str.erase(str.begin()+3,str.begin()+5);//abdg
```

### pop_back
`O(1)`で文字列の最後尾の文字を消去する。

```cpp
string str = "abcdefg";
str.pop_back(); // abcdef
```

###back
`O(1)`で文字列の最後尾の文字を消去してその文字を返す。

```cpp
string str = "abcdefg";
char c = str.back(); // abcdef
```
## count