#include map, set
mapを使う機会は余りなさそうだけど.よく使う場面が人物(string型)と数字を関連させたい時.
table表を作って動的計画法を行なう時とかにも結構大きな効果がある.
一番いいところはtableにすると見やすいところ.そして何より、
//aaaaaaは初めていれる文字とする table["aaaaaa"]++; //1 //わずか1行で済んでしまうので、便利.
順番にソートしたいが、元の配列のインデックス番号も保存しておきたい。
int arr[9] = {6, 4, 8, 0, 7, 6, 1}; map<int, int > mm; for(int i = 0; i < 9; i++) { mm.insert(mii::value_type(i, arr[i])); } //keyにしたがってソートを行なえるが、valueでは無理 //この例ではvalueに従ってソートを行なう予定でいるが、実際はできないので、最初から間違っている.
mapでの変数のアクセスの仕方。
for(it = rank.begin(); it != rank.end(); it++) { //必ずイテレータを使う.rank[i]とかやってしまうとエラーのため. ostringstream oss; if(it->second == -1) { oss << (it->first); //(*it)->first mapはpairをもとに実装されている. } else { oss << (it->first) << " " << (it->second); }
mm[6] = index; //みたいにしないと並び替えできません.それだと重複する可能性があるので、multimapを使う必要がある.
mapの使い道.
例えば、殆どの要素が0で計算がいらないが、かといって、Nが大きすぎて、0~N-1までの配列を作れない、あるいは、明らかに無駄な時、mapを使えば良い.
例) SRM474 div2 medium
maptest[60] //可能!
mapは-とか、+とか、使えないみたい. p - test.begin() //x
一回宣言して、もう一度同じ宣言すれば、書き換えられる. test[9] = 8; test[68] = 9; test[9] = 7; //test[9] = 7;の一つだけになる.
mapmap
のように、両刀使いすると、強力になるが、なんだか損した気分にもなる.もちろん全単射の条件が必要.
mapのinsertは若干注意が必要.
maptheMap; theMap.insert( make_pair( "Key 1", -1 ) ); make_pairをつかう //というか、 insert["Key 1"] = -1でOK //"Key 1"が既に存在している時、書き換えられてしまうので、 //if(theMap.find("Key 1") == theMap.end() ) みたいに条件分岐する必要がある.
set
setも-とか、+とか、使えないみたい. p - test.begin() //x lower ~ upperまでの範囲で何個あるかを調べたければ、(lower <= x <= upper) set::iterator beg, end; beg = validNum.lower_bound(lower); //upperなのにちゅうい。 end = validNum.upper_bound(upper); return vector (beg, end).size(); //こうするしかない? あとは、STLつかわずに、 set ::iterator beg, end, it; beg = validNum.lower_bound(lower); end = validNum.upper_bound(upper); int cnt = 0; for(it = beg; it != end; it++) { cnt++; } return cnt; とするとか。 1行でかける方法がみつかった! typename iterator_traits ::difference_type distance (InputIterator first, InputIterator last); つかえばイテレータ間の距離がわかる!! 注意として、第一引数がfirst, 第二引数がlastで逆にしないこと. return (int)distance(validNum.lower_bound(lower), validNum.upper_bound(upper) ); //これでおk
配列(vector
sets; for(vector ::iterator it = t.begin(); it != t.end(); it++) { s.insert(*it); } return s.size();
set>で座標の重複を避ける typedef pair dot; typedef pair pii; set > こういうこともできる.つかいようによっては便利な道具となる. ただ、自作の構造体は演算子をオーバーロードしないとinsertしたときに、 [<]とかのいき場所に困ってコンパイルエラーをおこすので、やや面倒.
なれてくると、アクロバット的なことも可能. int find(int n) { stringstream ss; ss << n; string num = ss.str(); return set(num.begin(), num.end()).size();
//setはset[0]とかで書けない。なので、一番初めの要素を取り出すときとかはイテレータを使う。 sets; int min = *s.begin();
lower_bound
key以下のイテレータを返す.
以下なので、同じ値ならば、その場所のイテレータを返す. *it <= n;
#includeiterator lower_bound( const key_type& key ); const_iterator lower_bound( const key_type& key ) const;
//prime 素数の集合 it2 = prime.lower_bound(17); //*it2 = 17;
upper_bound
は*it > n をみたす最小の(*it)