AtCoderのアルゴリズム実技検定にでてみようかなと思って、過去問を解いていました。どうやらF問題までACすると初級になれるようなので、F問題まで解いていました。E問題で躓いたものの、F問題までは時間内に通すことができました。
さて、今回はF問題でsortに比較関数を渡して、大文字小文字を無視してsortできるようにする必要があったので、実装してみました。
目次
1.コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
#define rep(i, n) for (int i = 0; i < (n); i++) | |
#define rep2(i, s, n) for (int i = (s); i < (n); i++) | |
using namespace std; | |
using ll = long long; | |
using P = pair<int, int>; | |
int main() { | |
string s; | |
cin >> s; | |
int count = 0; | |
vector<string> v; | |
string tmp; | |
for (char c : s) { | |
tmp.push_back(c); | |
if (c >= 65 && c <= 90) count++; | |
if (count == 2) { | |
v.push_back(tmp); | |
count = 0; | |
tmp.clear(); | |
} | |
} | |
sort(v.begin(), v.end(), [](const string& a, const string& b) { | |
for (int i = 0; i < min(a.size(), b.size()); i++) { | |
const auto a_char = tolower(a[i]); | |
const auto b_char = tolower(b[i]); | |
if (a_char != b_char) { | |
return a_char < b_char; | |
} | |
} | |
return a.size() < b.size(); | |
}); | |
for (string s : v) cout << s; | |
cout << endl; | |
return 0; | |
} |
2.ラムダ式を用いた比較関数
比較関数はclassで定義することもできますが、今回はラムダ式で定義しています。
比較関数は次の通り。
[](const string& a, const string& b) {
for (int i = 0; i < min(a.size(), b.size()); i++) {
const auto a_char = tolower(a[i]);
const auto b_char = tolower(b[i]);
if (a_char != b_char) {
return a_char < b_char;
}
}
return a.size() < b.size();
}
tolower関数は文字を小文字にする関数です。これによって一度小文字に変換してから比較するということを行っています。
コードは、文字列の辞書順比較[大文字と小文字を区別しない]より。
3.その他
比較関数について調べていたら、C++20の追加機能でよく使いそうなものを見つけたのでメモ。
formatライブラリのformat関数です。pythonのformatメソッドみたいな感じ。
例えば"Answer is 42"という文字列を作りたいとして、今までは、
string message = "Answer is " + to_string(42);
のように書いてたものを、
string message = format("Answer is {}",42);
と書けます。後者のほうが断然みやすいです。
また、numberライブラリというのが追加され、よく使う数学の数値が定義されました。円周率とかネイピア数とかlog2の値とか。
これでヘッダーで値を定義しなくても良くなるんやな・・・としみじみ思いました。
C++20では一貫比較というものが追加され、これが便利そう。便利そうなんですが、レファレンスを読んでもよくわからない。6つの比較演算子を一挙に行えるという認識でいいのかな?sort関数のサンプルコードの一番下に一貫比較を用いたコードが示されています。
4.参考文献
cpprefjp – C++日本語レファレンス std::sort