皆さんは競プロをするときにエディタのスニペット機能を使っていますか? 私のスニペットを見せます。 言語はC++、エディタはVSCodeです。
out
cout << ans << "\n"; cout << ans << ans << "\n";
"out": { "body": "cout << ${1:ans} << \"\\n\";", "prefix": "out" }, "out2": { "body": [ "cout << ${1:ans} << ${2:ans} << \"\\n\";" ], "description": "out2", "prefix": "out2" },
値を標準出力する。 使用率はダントツで1位です。
YesNo
cout << (ans ? "Yes" : "No") << "\n";
"yesno": { "body": [ "cout << (${1:ans} ? ${2|\"Yes\" : \"No\",\"YES\" : \"NO\",\"yes\" : \"no\"|}) << \"\\n\";" ], "description": "yesno", "prefix": "yesno" }
YesかNoを出力する。 AtCoderがcase-sensitiveなのでいくつか選べるようにした。
コンテナをスペース区切りで出力
for (auto i = vec.begin(); i != vec.end(); i++) { cout << *i << (i != vec.end() - 1 ? ' ' : '\n'); }
"output container separated by spaces": { "body": [ "for (auto ${1:i} = ${2:vec}.begin(); ${1:i} != ${2:vec}.end(); ${1:i}++) {", " cout << *${1:i} << (${1:i} != ${2:vec}.end() - 1 ? ' ' : '\\n');", "}", "$0" ], "description": "output container separated by spaces", "prefix": "outspaces" },
コンテナの値を順にスペース区切りで出力して最後は改行する。 for内の条件演算子は速度に悪いが問題ないだろう。
all
a.begin(), a.end()
"all": { "body": "$1.begin(), $1.end()$0", "prefix": "all" },
コンテナのメンバ関数begin
とend
を同時に書く。
sort
, lower_bound
などで使う。
max
max_hoge = max(hoge_i, max_hoge);
"max": { "body": [ "${1:max_hoge} = max(${2:hoge_i}, $1);" ], "description": "max", "prefix": "max" },
最大値max_hoge
をhoge_i
で更新する。
minもある。
cumulative_sum
vector<int> csv(n + 1); csv[0] = 0; for (int i = 0; i < n; i++) csv[i + 1] = csv[i] + v[i];
"cumulative_sum": { "body": [ "vector<int> cs${1:a}(${2:n} + 1);", "cs${1:a}[0] = 0;", "for (int i = 0; i < ${2:n}; i++)", " cs${1:a}[i + 1] = cs${1:a}[i] + ${1:a}[i];", "$0" ], "description": "cumulative_sum", "prefix": "cumulative_sum" },
累積和をさっと書く。
input vector
vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i];
"inputvec": { "body": [ "vector<${1:int}> ${2:a}(${3:n});", "for (int i = 0; i < $3; i++) cin >> $2[i];", "" ], "description": "inputvec", "prefix": "inputvec" },
標準入力から配列を受け取る。 型・変数名・配列長はコーディング時に入力できる。 ほかにも標準入力スニペットはいくつか用意している。
inf
constexpr int INF = 1000000000 + 8;
"inf": { "body": [ "constexpr int INF = 1000000000 + 8;" ], "description": "inf", "prefix": "inf" },
テンプレを短くしたいのでINF
とかもテンプレからスニペットに移しました。
ceil
constexpr int ceil(long long a, long long b) { return (a + b - 1) / b; }
"ceil": { "body": [ "constexpr int ceil(long long a, long long b) { return (a + b - 1) / b; }" ], "description": "ceil", "prefix": "ceil" },
整数を切り上げて割り算する関数。 たまに使う関数はテンプレではなくスニペットに移しました。
log2n
constexpr long long log2n(long long n) { long long log_n = 1; while ((1LL << log_n) < n) log_n++; return log_n; }
"log2n": { "body": [ "constexpr long long log2n(long long n) {", " long long log_n = 1;", " while ((1LL << log_n) < n) log_n++;", " return log_n;", "}", "" ], "description": "log2n", "prefix": "log2n" },
を返す関数。
このコードはよく見るので関数化してスニペットに入れた。
多分あってる。
めぐる式二分探索
// めぐる式二分探索 // (ng, ok] or [ok, ng) // 条件を満たす最小(最大)のindex okと // 条件を満たさない最大(最小)のindex ngを探索する int ok = n; // 条件を満たすindex int ng = -1; // 条件を満たさないindex while (abs(ok - ng) > 1) { int mid = (ok + ng) / 2; if (isSatisfy(mid)) ok = mid; else ng = mid; }
"meguru_binary_search": { "body": [ " // めぐる式二分探索", " // (ng, ok] or [ok, ng)", " // 条件を満たす最小(最大)のindex okと", " // 条件を満たさない最大(最小)のindex ngを探索する", " int ok = ${1:n}; // 条件を満たすindex", " int ng = ${2:-1}; // 条件を満たさないindex", " while (abs(ok - ng) > 1) {", " int mid = (ok + ng) / 2;", " if (${3:isSatisfy}(mid))", " ok = mid;", " else", " ng = mid;", " }", "" ], "description": "meguru_binary_search", "prefix": "meguru_binary_search" },
めぐる式二分探索です。
感想
outなど入出力のスニペットは非常に便利だと思います。 それ以外はたまに書くコードの置き場になっている。
リンク
- Snippets in Visual Studio Code: 公式ドキュメント。
- snippet generator: コードから楽にスニペットを作れる。