AtCoderに取り組んでいて迷うことが多々あったので、
C++における文字列の操作についてまとめます。(適宜追記予定です)
##基本
文字列変数の宣言・値の代入を行い、標準出力します。
#include<iostream>
#include<string>
using namespace std;
int main() {
string s1 = "testtest";
string s2 = "";
string s3 = "TEST";
cout << "s1=" << s1 << ", s2=" << s2 << ", s3=" << s3 << endl;
}
s1=testtest, s2=, s3=TEST
##n番目文字の抽出
[ ]で取得したい文字列のインデックスを指定します。
s1 = "testtest";
char c = s1[3];
cout << "c = " << c << endl;
c = t
##文字列の長さを取得
size()を使用します。
s1 = "testtest";
s2 = "";
cout << "s1.size()= " << s1.size() << endl;
cout << "s2.size()= " << s2.size() << endl;
s1.size()= 8
s2.size()= 0
##文字列が空かどうか判定
empty()を使用します。
S1 = "testtest";
s2 = "";
cout << "s1.empty = " << s1.empty() << endl;
cout << "s2.empty = " << s2.empty() << endl;
s1.empty = 0
s2.empty = 1
s2は空の文字列なので1 (=true)が返ってきます。
##文字列の連結
シンプルに + で足し算できます
string s1 = "testtest";
string s3 = "TEST";
string s1pls3 = s1 + s3;
cout << "s1 + s3 = " << s1pls3 << endl;
s1 + s3 = testtestTEST
##文字列の分割
n番目以降の文字列を取り出す場合はsubstr(n)とします。
s1 = "testtest";
cout << "s1.substr(3) = " << s1.substr(3) << endl;
s1.substr(3) = ttest
n番目以降の文字列をm文字だけ取り出す場合はsubstr(n, m)とします。
s1 = "testtest";
cout << "s1.substr(3,3) = " << s1.substr(3,3) << endl;
s1.substr(3,3) = tte
##文字列を任意の文字で分割
任意の文字での文字列分割(split)はc++に定義されていません。
自分で実装しましょう!
参考: C++におけるstringのsplit
##文字列の削除
n文字目以降の文字列を削除したい場合はerase(n)とします。
s1 = "testtest";
cout << "s1.erase(3) = " << s1.erase(3) << endl;
s1.erase(3) = tes
n文字目以降の文字列をm文字だけ削除したい場合はerase(n, m)とします。
s1 = "testtest";
cout << "s1.erase(3,2) = " << s1.erase(3, 2) << endl;
s1.erase(3,2) = tesest
##文字列の挿入
n文字目から文字列Xを挿入したい場合はinsert(n,X)とします。
s1 = "testtest";
cout << "s1.insert(3,IN) = " << s1.insert(3, "IN") << endl;
s1.insert(3,IN) = tesINttest
##文字列の検索
探索したい文字列Xを用いてfind(X)とすると、該当する位置を返します。
s1 = "testtest";
cout << "s1.find(s) = " << s1.find("s") << endl;
s1.find(s) = 2
sの最初の出現位置が返ります。
もしも検索文字列が見つからない場合には以下のようになります。
s1 = "testtest";
cout << "s1.find(w) = " << s1.find("w") << endl;
s1.find(w) = 18446744073709551615
検索文字列が見つからないときは string::npos という値が返るようです。
それが何故こんな大きな数字になるのかは、以下の記事で解説されています。
std::string::nposの正体
では string::nposを使って、検索失敗の場合の場合分けをしてみます。
s1 = "testtest";
cout << "s1.find(W) == string::npos --> " << (s1.find("W") == string::npos) << endl;
s1.find(W) == string::npos --> 1
"testtest" の中に "W"は含まれないので、string::nposとなっています(1 (=true)が返ります)。
##文字列の置換
n番目から数えてm個の文字列をXに置換したい場合はreplace(n,m,X)とします。
s1 = "testtest";
cout << "s1.replace(2, 1, W) = " << s1.replace(2, 1, "W") << endl;
s1.replace(2, 1, W) = teWttest
##文字列の比較(一致判別)
文字列と文字を用いた比較の例です。
//文字列
if(s1 == "test" ){
cout << "test" << endl;
}
//文字
if(s1[0] == 't' ){
cout << "t" << endl;
}
##文字列の比較2(小文字大文字英数字判別)
英字大文字小文字数字の判定。(ひらがなカタカナ漢字の判別は、またどこかで必要になったら調べて追記します)
//文字が英小文字かどうか判定
if(s1[0] >= 'a' && s1[0] <= 'z'){
cout << "small" << endl;
//文字が英大文字かどうか判定
}else if(s1[0] >= 'A' && s1[0] <= 'Z'){
cout << "large" << endl;
//文字が数字かどうか判定
}else if(s1[0] >= '0'){
cout << "number" << endl;
}
もしくは #includeとして、isalpha(判別したい文字)や isdigit(判別したい文字)を利用できます。
#include<iostream>
#include <ctype.h>
using namespace std;
int main() {
char s;
cout << "input: " ;
cin >> s;
cout << "isalpha: "<< isalpha(s) << endl;//アルファベットかどうか
cout << "isdigit: "<< isdigit(s) << endl;//数字かどうか
cout << "islower: "<< islower(s) << endl;//小文字かどうか
cout << "isupper: "<< isupper(s) << endl;//大文字かどうか
}
//アルファベット&小文字入力
input: a
isalpha: 1024
isdigit: 0
islower: 512
isupper: 0
//数字入力
input: 1
isalpha: 0
isdigit: 1
islower: 0
isupper: 0
//アルファベット&大文字入力
input: A
isalpha: 1024
isdigit: 0
islower: 0
isupper: 256
##文字列から数字型へ変換
sstream を使用して、string型に入った数字文字列をint型に変換します。
#include<iostream>
#include<string>
#include <sstream>
using namespace std;
int main() {
string s1;
istringstream ss1;
int p1;
cin >> s1;
ss1 = istringstream(s1);
ss1 >> p1;
//数字が入ったp1を操作
}
##文字型から数字型へ変換
一文字ずつなら難しいことしなくても数字型にできます。
string s = "1";
int a = s[0]-'0';
a += 5;
cout << a << endl;
6
##文字列の並び替え
sortを使用して降順昇順並び替えを行います。
(英数字以外には使えないかな...)
s1 = "482tTest";
sort(s1.begin(), s1.end());
cout << s1 << endl;
sort(s1.begin(), s1.end(), greater<char>());
cout << s1 << endl;
248Testt //数字1-9▶英大文字A-Z▶英小文字a-z
ttseT842 //英小文字z-a▶英大文字Z-A▶数字9-1
##英文字をアルファベット順でN個後にずらして出力
参考: abc146 B
こんな感じ?
string s1 = "test";
int N = 5;
printf("%c", (s1[0]+N));
##末尾の文字削除/末尾に文字追加
参考: abc043 B
pop, pushが使える
string s1 = "test";
//末尾に'2'を追加
s1.push_back('2');
//末尾の文字削除
s1.pop_back();
##回文判定
reverseで反転を行い、元文字列と比較することで実現できます。
(後日 追記)
以上です。
また何かあれば追記していきます。