lower_bound()
とupper_bound()
でこんなことができたんだなーと発見できて楽しかったので、時間で区間を指定して抽出するのをやってみました。
簡易的なBoost.Interval Containerとして使えていいですね。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::vector<std::string> times = {
"2018/12/31 00:00",
"2019/01/01 00:01",
"2019/01/01 01:15",
"2019/01/01 03:30",
"2019/01/01 08:23",
"2019/01/01 10:50",
"2019/01/01 13:20",
"2019/01/01 15:30",
"2019/01/01 18:00",
"2019/01/03 23:59",
};
auto first = std::lower_bound(times.begin(), times.end(), "2019/01/01 00:00");
auto last = std::upper_bound(times.begin(), times.end(), "2019/01/01 12:00");
for (; first != last; ++first) {
std::cout << *first << std::endl;
}
}
出力:
2019/01/01 00:01
2019/01/01 01:15
2019/01/01 03:30
2019/01/01 08:23
2019/01/01 10:50
補足ですが、UTF-8とかの文字コードを指定しなくてもC++の規格で文字'0'
から'9'
までは順序が規定されているので、文字列の辞書順比較で日時の大小が決められます。月をJan、Febとかにしたら意図した動作にはなりません。数字以外の区切り文字とかが共通ならいけるので、「2019年01月01日」とかなら大丈夫です。月と日が2桁ゼロ埋めで揃えないといけない縛りとかはあります。
境界値のお試し。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
std::vector<std::string> times = {
"2018/12/31 00:00",
"2019/01/01 00:00",
"2019/01/01 00:01",
"2019/01/01 01:15",
"2019/01/01 03:30",
"2019/01/01 08:23",
"2019/01/01 10:50",
"2019/01/01 11:59",
"2019/01/01 12:00",
"2019/01/01 13:20",
"2019/01/01 15:30",
"2019/01/01 18:00",
"2019/01/03 23:59",
};
auto first = std::lower_bound(times.begin(), times.end(), "2019/01/01 00:00");
auto last = std::upper_bound(times.begin(), times.end(), "2019/01/01 12:00");
for (; first != last; ++first) {
std::cout << *first << std::endl;
}
}
出力:
2019/01/01 00:00
2019/01/01 00:01
2019/01/01 01:15
2019/01/01 03:30
2019/01/01 08:23
2019/01/01 10:50
2019/01/01 11:59
2019/01/01 12:00