Upload
yak1ex
View
1.079
Download
0
Embed Size (px)
Citation preview
ICL(Interval Container Library)
2011/2/26 Boost 勉強会 #4 未発表
@yak_ex / 新 康孝
詳解紹介
自己紹介• 氏名: 新 康孝 ( あたらし やすたか )• Twitter ID: yak_ex• Web: http://yak3.myhome.cx:8080/junks
• C++ / Perl が主戦場• 現在、仕事でコードに触れていないので
競技プログラミング( TopCoder 、 Codeforces )で潤い補充
• 闇の軍団に憧れるただの C++ 好き– 今回は ICL のさわりだけ、というかさわりしか分
からない
ぼくのかんがえた「ぶーすと」のぶんるい
実装より
アプリより
大規模小規模
実装より
アプリより
大規模小規模
operatorstimer rational type_traits
random
array
graph
regex
lexical_cast
iterators
test
crc
~ 1.25
any
function
tuple
thread
tokenizerpool
ぼくのかんがえた「ぶーすと」のぶんるい
progress_display たんはココ
実装より
アプリより
大規模小規模
timer rational type_traits
random
array
graph
regex
lexical_cast
iterators
test
crc
~ 1.30
any
function
tuple
thread
preprocessor
異次元
lambda
date_time
format
multi_array
filesystem
mploptional
spirit
tokenizerpool
ぼくのかんがえた「ぶーすと」のぶんるい
progress_display たんはココ
timer rational
実装より
アプリより
大規模小規模
type_traits
random
array
graph
regex
lexical_cast
iterators
test
crc
~ 1.35
any
function
tuple
thread
preprocessor
異次元
lambda
date_time
format
multi_array
filesystem
mploptional
spirit
variant
multi_index
program_options
range
serialization
parameterptr_container
wave
foreach
statechart
typeof
xpressive
asio
bimap
gil
fusion
interprocess
intrusive
tokenizerpool
ぼくのかんがえた「ぶーすと」のぶんるい
progress_display たんはココ
timer rational
実装より
アプリより
大規模小規模
type_traits
random
array
graph
regex
lexical_cast
iterators
test
crc
~ 1.40
any
function
tuple
thread
preprocessor
異次元
lambda
date_time
format
multi_array
filesystem
mploptional
spirit
variant
multi_index
program_options
range
serialization
parameterptr_container
wave
foreach
statechart
typeof
xpressive
asio
bimap
gil
fusion
interprocess
intrusive
accmulators
unordered
proto
scope_exit
flyweight
tokenizerpool
ぼくのかんがえた「ぶーすと」のぶんるい
progress_display たんはココ
timer rational
実装より
アプリより
大規模小規模
type_traits
random
array
graph
regex
lexical_cast
iterators
test
crc
~ 1.45
any
function
tuple
thread
preprocessor
異次元
lambda
date_time
format
multi_array
filesystem
mploptional
spirit
variant
multi_index
program_options
range
serialization
parameterptr_container
wave
foreach
statechart
typeof
xpressive
asio
bimap
gil
fusion
interprocess
intrusive
accmulators
unordered
proto
scope_exit
flyweight
tokenizer
property_tree
uuid
pool
msmpolygon
ぼくのかんがえた「ぶーすと」のぶんるい
progress_display たんはココ
timer rational
実装より
アプリより
大規模小規模
type_traits
random
array
graph
regex
lexical_cast
iterators
test
crc
~ 1.46
any
function
tuple
thread
preprocessor
異次元
lambda
date_time
format
multi_array
filesystem
mploptional
spirit
variant
multi_index
program_options
range
serialization
parameterptr_container
wave
foreach
statechart
typeof
xpressive
asio
bimap
gil
fusion
interprocess
intrusive
accmulators
unordered
proto
scope_exit
flyweight
tokenizer
property_tree
uuid
pool
msmpolygonICL
ぼくのかんがえた「ぶーすと」のぶんるい
progress_display たんはココ
ここで競技コーディングのお時間です• akira さん(仮名)はパーティーを開くことになりまし
た。 N 人のお客さんが参加する予定ですが参加時間帯[si, ti) が皆ばらばらです。場所の予約のために参加人数の最も多い時間帯を知りたいのでプログラムを作って akira さんを助けてあげましょう。
– 1 N 1000≦ ≦– -109 s≦ i < ti 10≦ 9, si, ti は整数 (i=1,2,…,N)– 参加人数が同じ時間帯が隣接している場合、参加者が異なって
いても一つの時間帯と見なす– 同一参加人数の時間帯が複数ある場合は最長の時間帯を、同じ
長さの時間帯が複数ある場合は開始時刻がもっとも早い時間帯を返す
– 入力: N< 改行 >s1< 空白 >t1< 改行 >…sN< 空白 >tN< 改行 >– 出力:開始時刻 < 空白 > 終了時刻 < 空白 > 人数 < 改行 >
解答例全文 using ICL#include <iostream>#include <algorithm>#include <utility>#include <boost/icl/interval_map.hpp>
int main(void){ boost::icl::interval_map<int, int> sum; int n; std::cin >> n; for(int i = 0; i < n; ++i) { int s, t; std::cin >> s >> t; sum += std::make_pair(boost::icl::interval<int>::right_open(s, t), 1); } typedef boost::icl::interval_map<int, int>::value_type value_type; auto it = max_element(sum.begin(), sum.end(), [](const value_type &v1, const value_type &v2) { return v1.second < v2.second || (v1.second == v2.second && v1.first.upper() - v1.first.lower() < v2.first.upper() - v2.first.lower()) || (v1.second == v2.second && v1.first.upper() - v1.first.lower() == v2.first.upper() - v2.first.lower() && v1.first.lower() < v2.first.lower()); }); std::cout << it->first.lower() << ' ' << it->first.upper() << ' ' << it->second << std::endl; return 0;}
#include 含めて 25 行
解答例全文 using ICL#include <iostream>#include <algorithm>#include <utility>#include <boost/icl/interval_map.hpp>
int main(void){ boost::icl::interval_map<int, int> sum; int n; std::cin >> n; for(int i = 0; i < n; ++i) { int s, t; std::cin >> s >> t; sum += std::make_pair(boost::icl::interval<int>::right_open(s, t), 1); } typedef boost::icl::interval_map<int, int>::value_type value_type; auto it = max_element(sum.begin(), sum.end(), [](const value_type &v1, const value_type &v2) { return v1.second < v2.second || (v1.second == v2.second && v1.first.upper() - v1.first.lower() < v2.first.upper() - v2.first.lower()) || (v1.second == v2.second && v1.first.upper() - v1.first.lower() == v2.first.upper() - v2.first.lower() && v1.first.lower() < v2.first.lower()); }); std::cout << it->first.lower() << ' ' << it->first.upper() << ' ' << it->second << std::endl; return 0;}
ヘッダのインクルード
入力と登録
最大値取得
出力
解答例 入力と登録 boost::icl::interval_map<int, int> sum; int n; std::cin >> n; for(int i = 0; i < n; ++i) { int s, t; std::cin >> s >> t; sum += std::make_pair(boost::icl::interval<int>::right_open(s, t), 1); }
右開区間 [s, t)
1
1
1 1
2
+ 1
1
+
1 1
1split_interval_map
interval_map
今回は数だが集合も可能
解答例 最大値取得typedef boost::icl::interval_map<int, int>::value_type value_type; auto it = max_element(sum.begin(), sum.end(), [](const value_type &v1, const
value_type &v2) { return v1.second < v2.second || (v1.second == v2.second && v1.first.upper() - v1.first.lower() < v2.first.upper() - v2.first.lower()) || (v1.second == v2.second && v1.first.upper() - v1.first.lower() == v2.first.upper() - v2.first.lower() && v1.first.lower() < v2.first.lower()); });
// 集計値は second// 区間は first (upper(), lower() で境界値 )
集計された区間の結果を iteration 可能なので普通に max_element で最大値取得
Interval Container Library• 1.46 で導入• 開区間、閉区間等全部取り扱い可能• 区間に対する集合演算、「集計」が可能• interval_set,
interval_map
• 区間の統合方法として join, separate, split を選択可能• ストリーム出力有り(例: {(1,3][4.6](7,8]} )• Traits 用意すれば自前の interval を突っ込むことも可能• 数値に限定されないので例えば
cotinuous_interval<std::string> w(“a”, “c”) // right_open
とか書くと a, b で始まる文字列全部を表すことになる。• Example がいっぱいなのでそれ見れば OK
interval_set a
interval_set b
interval_set a - b