Library
C++ のライブラリに関する tips.
std::string
string 型を整数へ変換
- cplusplus.com: std::stoll
stoi: string to intstol: string to longstoll: string to long longstoull: string to unsigned long long
基本(参考:)
#include <bits/stdc++.h>using namespace std;int main() {// converting decimal number.string dec_num = "9876543210";cout << "dec_num = " <<stol(dec_num, nullptr, 10) << "\n";// converting hexadecimal number.string hex_num = "FFFFFF";cout << "hex_num = " <<stol(hex_num, nullptr, 16) << "\n";// converting binary number.string binary_num = "1111111";cout << "binary_num = " <<stol(binary_num, nullptr, 2) << "\n";return 0;}
output
dec_num = 9876543210hex_num = 16777215binary_num = 127
- 例
#include <iostream> // std::cout#include <string> // std::string, std::stollint main (){std::string str = "8246821 0xffff 020";std::string::size_type sz = 0; // alias of size_twhile (!str.empty()) {long long ll = std::stoll(str, &sz, 0);std::cout << str.substr(0,sz) << " interpreted as " << ll << '\n';str = str.substr(sz);}return 0;}
output
8246821 interpreted as 82468210xffff interpreted as 65535020 interpreted as 16
string::substr - 部分文字列の取得
basic_string substr(size_type pos = 0, size_type n = npos) const;
部分文字列を取得する.pos 番目から n 要素の文字列を返す.n を省略した場合は文字列の最後までを取り出す.
- ex
std::string str = "Hello, world!";// (0-origin で)2 番目から 3 文字取り出すstd::string result = str.substr(2, 6);std::cout << result << std::endl;//>>> llo, w(全 6 文字)// (0-origin で)2 番目以降の文字列を取得std::string result1 = str.substr(2);std::cout << result1 << std::endl;//>>> llo, world!
- 特定の文字を検索してその文字を境に分断する.
std::string str = "price:3000";std::string key;int value;int idx_split = (int)str.find(":"); // 3key = str.substr(0, idx_split); // pricevalue = stoi(str.substr(idx_split+1)); // "3000" -> 3000std::cout << "key: " << key << std::endl; // key: pricestd::cout << "value: " << value << std::endl; // value: 3000
文字列の比較演算,辞書順
比較演算子で文字列を比較する場合,「辞書で速く出てくる単語ほど小さい」と処理される.文字列だけでなく,数字同士の比較も同様である.
単純な単語の比較
atcoder < atlas
短い方が小さい
abc < abcd
数字の比較
'0' < '2'"22" < "2222"
特定の 1 文字の文字列の生成
std::string のコンストラクタに長さと何らかの文字を与えると,その文字を長さ分だけ連結した文字列を生成してくれる.
char ch = 'a';std::string str(5, ch);std::cout << str << "\n"; // aaaaa
1 桁の数字を受け取ってその数字を 10 個並べた文字列を生成する.
int a;std::cin >> a;std::string str(10, a + '0');std::cout << str << "\n";
文字列をひっくり返す: reverse()
イテレータを反転させる.
string str = "abcde";cout << str << "\n";reverse(str.begin(), str.end())cout << str << "\n";
文字列の検索,含まれるかどうかの判定
std::string::find を使用する.
str.find("検索文字列")- 戻り値
- 見つかった場合:インデックス
- 見つからなかった場合:
std::string::npos(見つからないことを示すメンバ定数)
- 戻り値
std::string s = "abc";if (s.find("b") != std::string::npos) {cout << "文字列`b`が見つかりました" << "\n";}
std::vector
vec.push_back() と vec.emplace_back()
emplace_back は,実引数がコンテナの要素型と異なるときに、push_back よりも動作が早くなり、それ以外の場合ではほとんど変わらない(実引数が単に変数のときなど).単に整数型,実数型などの数値型を入れるときはpush_backでよい.std::pairなどのオブジェクトを入れるときはemplace_back を使うとよい.
push_back だと vec に入れたいオブジェクトが「2 回コンストラクトされる」ため無駄がある.
std::vector.push_back() の内部の動作
- 一時的にオブジェクトがコンストラクトされる.
- それが std::vector の新規オブジェクトとしてコンストラクトされる.
- 1 で作られたオブジェクトが破棄される.
このようにコンストラクタが 2 回呼び出されている.これは無駄. C++11 以降では,コンストラクタの引数から直接コンテナの新規オブジェクトが生成できる関数が用意された.
それがemplace_back.
2 次元配列
2 次元配列の宣言
vector<int> vec(N); // 1×N 初期化なしvector<int> vec(N, 0); // 1×N 0で初期化// 2次元配列vector< vector<int> > vec = \{\{1, 2, 3\}, \{4, 5, 6\}\};// 20×10の配列: 0で初期化vector<vector<int>> vec(20, vector<int>(10, 0));// (N, M)の多次元配列vector<vector<int>> vec(N, vector<int>(M, 0)); // 0で初期化
2 次元配列の出力:関数
template <class T> void print2DVec(vector< vector<T> >& vec) {REP(i, vec.size()) {REP(j, vec.front().size()) { // vec.front() == vec.at(0)if (j) cout << " ";cout << vec.at(i).at(j); // vec[i][j]}cout << endl;}}
イテレータの宣言
イテレータを定義するとき,std::vector<int>::iteratorとタイプするのは面倒.そんなときは型推論のautoを使用すると記述量が少なくなる(競プロのみ.システムのコードを書くときは非推奨.).
- 例)配列の最大値のイテレータを返す関数
max_element
- std::vector<int>::iterator iter = max_element(vec.begin(), vec.end());+ auto iter = max_element(vec.begin(), vec.end());
std::map / std::unordered_map
std::set / std::unordered_set
hoge
std::ios / std::iomanip(パディングなど)
パディング
左埋めのパディング
// 必用なヘッダーインクルード#include <ios> // std::left, std::right#include <iomanip> // std::setw(int), std::setfill(char)// 直後の要素をパディング#define zero_pad(num) setfill('0') << std::right << setw(num)#define space_pad(num) setfill(' ') << std::right << setw(num)// std::left とすれば,右に '0' を埋めることができるint main() {// inputint a = 33, b = 5555, c = 67891;// calculationcout << zero_pad(0) << a << "\n";cout << zero_pad(2) << a << "\n";cout << zero_pad(4) << a << "\n";cout << zero_pad(4) << b << "\n";cout << zero_pad(6) << b << "\n";cout << zero_pad(10) << b << "\n";cout << zero_pad(3) << b << "\n";cout << zero_pad(5) << b << "\n";cout << zero_pad(10) << b << "\n";return 0;}
出力
33330033555500555500000055555555055550000005555
標準出力での精度
出力に精度が必要なときは,std::iomanip の std::setprecision(桁数) を使う.std::cout と合わせて利用する.
下記のコードを main 関数内で書いておけば,double 型などの数値が 20 桁分出力される.
int main() {std::cout << fixed << setprecision(20);const double PI = acos(-1);std::cout << PI << "\n";return 0;}