きっかけ
始めてArCoderのABCに参加して,C++全然理解できていないことが分かったので,基礎中の基礎を簡単にまとめていきます.
拡張子
C++の拡張子は複数あるらしい.
.cpp, .c++, .cxx, .cc などだが,一般的には .cpp らしい
全ライブラリ読み込み
とりあえずこれを書いておけばC++の機能を「全て」読み込んでくれるのでエラーがあまり出ない.
競技プログラミングならこれでOK.
#include <bits/stdc++.h>
long long とか長いやつを略す
using ll = long long;
using ull = unsigned long long;
入出力
int a;
cin >> a; //入力
cout << a; //出力
文字列変換
int から String
int num = 123;
string str = std::to_string(num);
// str = "123"
String から int
strimg str = "123";
int num = std::stoi(str);
// num = 123
String から long long
string str = "123";
long long num = std::stoll(str);
char から int
char c = '1';
int i = c - '0';
文字列の分割
n番目以降を取り出す場合(0からスタート)
string s1 = "ABCDEFGHIJK...";
string s2 = s1.substr(3);
// s2 = "DEFGHIJK..."
n番目以降の文字をm文字だけ取り出す場合
string s1 = "ABCDEFGHIJK...";
string s2 = s1.substr(3,3);
// s2 = "DEF"
文字の置き換え
replace()
string型にはreplace()があり,これは指定した位置からN文字を文字列で置き換える
string s1 = "12345";
string s2 = "abcde";
// 1番目から2文字を、s2文字列で置き換える
s1.replace(1, 2, s2);
// s1 = "1abcde45"
find()
find()を用いて特定文字の場所を探すことができる.ただし一番先頭の場所だけ.
文字列が見つからなかった場合にはnposという値を返す.数値的には-1となる.
std::string str = "algorithm, programming, engineer";
int position = str.find("programming");
// position = 11
すべて置き換え
replace()とfind()を組み合わせることですべての文字列を置き換えることができる.
string replaceAll(string &S, string from, string to){
int pos = S.find(from);
int len = from.length();
while(pos != -1){
S.replace(pos, len, to);
pos = S.find(from);
}
return S;
}
ビット演算
ビットに対する演算だが,数値型でも使用可能.
~x // 否定
x << y // 左シフト
x >> b // 右シフト
x & y // 論理積
x | y // 論理和
x ^ y // 排他的論理和
特に排他的論理和は変数x対して,aとbとをif文なしで反転させるときに使うと便利!
int a = 0;
int b = 1;
a = a ^ b ^ a ;
// a = 1
反転させるのは他にもこんなやり方もある
int a = 0;
int b = 1;
a = a + b - a ;
// a = 1
bitset型
0と1のみの型のためメモリ使用量が少ない.
あるかないかを保存したい時に便利かも?
# 8ビット
bitset<8> b;
# 初期値を設定することもできる
bitset<8> b("10000011");
count()
count()メソッドを使うことで1の数を数えることも可能
bitset<8> b("10000011");
b.count();
// 3
Vector
C++にはvectorというコンテナがあり,動的配列ができる.またリストというコンテナもあるがこちらは最初に挿入したりもできるらしい.
#include<vector>
// 宣言
vector<int> vec;
// プッシュ
vec.emplace_back(4);
// 参照
cout << vec[0] << endl;
// vec[0] = 4
// 先頭のデータ取得
int front = vec.front();
// 最後のデータ取得
int back = vec.back();
2次元配列
vectorでは2次元配列も可能
vector<vector<int>> vv;
# 大きさを決める場合
vector<vector<int>> v(n, vector<int>(m));
repマクロ
何度も使うfor文をマクロで簡単にする方法
// 指定回数
#define rep(i, n) for(int i = 0 ; i < (int)n ; i++)
// 初期化あり
#define rep(i,init,n) for(int i = (int)init ; i < (int)n ; i++)
範囲for文
配列やコンテナを簡潔にあつかうためのfor文の別表現
// 読み込むとき
int len = 5;
vector<int> A(len);
for(auto&& a : A)
cin >> a;
// 出力するとき
for(auto&&a : A)
cout << a << " ";
番外編:コンパイル&実行コマンド
C++もGCCでコンパイルできるが,Cと少しコマンドが変わる
// デフォルト
g++ filename.cpp &&./a.out
// ファイル読み込みも含む
g++ filename.cpp && ./a.out < input.txt
番外編:メモリ不足
Segmentation fault エラーが出た時は,参照エラーの場合もあるが,メモリ不足の場合もある.
bashに以下のコマンドを打つとメモリ容量の確認と,制限を解除することができる.
// 容量確認
$ ulimit -a // いろいろ出るがtuck sizeのところを見るとわかる
// 容量開放
$ ulimit -s unlimited
テンプレート
上記を踏まえて一番最初のテンプレートを考えてみた.
この通りに書けば,何かと便利.
#include<bits/sdtc++.h>
using namespace std;
using ull = unsigned long long
#define rep(i,n) for(int i = 0 ; i < (int)n ; i++)
int main(){
return 0;
}
まとめ
ほかの言語のやり方は知っていても,C++だとわからないものが多かった.これからも随時更新していく.