Movatterモバイル変換


[0]ホーム

URL:


Uploaded byyak1ex
PDF, PPTX1,799 views

C++0x in programming competition

Embed presentation

Download as PDF, PPTX
競技プログラミングからみたC++0x     OSC名古屋2011 8/20(土)   はじめての競技プログラミング 蛇足   @yak_ex / 新 康孝 (CSNagoya)
自己紹介 氏名: 新 康孝 (あたらし やすたか) Twitter ID: yak_ex Web: http://yak3.myhome.cx:8080/junks C++ / Perl が主戦場 現在、仕事でコードに触れていないので  競技プログラミング(TopCoder、Codeforces)で  潤い補充 闇の軍団に憧れるただの C++ 好き
C++0x とは 国際標準化機構 ISO で規格化されている C++ 規格(ISO  14882)の次期版仮称   200x 年代に発行予定だったが間に合わなかったため 0x は 16 進プ    レフィクスということに    http://www2.research.att.com/~bs/C++0xFAQ.html 先頃 Final Draft が承認され規格発行を待つ状態であり正  式名称 14882:2011 となる予定 小修正だった 14882:2003 とは異なり、言語自体また標準ラ  イブラリに非常に大きな変更が加えられている 本稿では競技プログラミングから見た C++0x の利点につい  て紹介する   Codeforces で gcc 4.6 での C++0x 機能が使えるのでそれを基準と    して説明する
目次 auto Range-based for Lambda tuple initializer_list unordered_map / unordered_set 新規アルゴリズム (iota, all_of) ちょっとした改善 (map::at) 対応微妙(regex / emplace)
auto 例えば set の要素についてループする場合、  Iterator の型を書くのが面倒   set<int> s;   for(set<int>::iterator it = s.begin(); it != s.end(); ++it) {             if(*it == 5) it = s.erase(it);   } →auto にしておけばコンパイラが型を導出してくれる   set<int> s;   for(auto it = s.begin(); it != s.end(); ++it) {             if(*it == 5) it = s.erase(it);   }
Range-based for 例えば単純に set の要素についてループする場合、  C++03では色々と面倒   std::set<int> s;   for(std::set<int>::iterator it = s.begin(); it != s.end(); ++it)      std::cout << *it << std::endl; auto でもやっぱり微妙   std::set<int> s;   for(auto it = s.begin(); it != s.end(); ++it)      std::cout << *it << std::endl; Range-based for ループですっきり   set<int> s;   for(auto v : s)      std::cout << v << std::endl; コンテナ s の各要素を v に割り当ててループ
lambda (無名関数オブジェクト) <algorithm>は便利だけど関数オブジェクト書くのが  面倒でループで書いてしまう   // 関数オブジェクト   struct check2nd   {      check2nd(const int &n) : n(n) {}      bool operator()(const std::pair<int, int> &p) { return p.second == n; }      const int &n;   };   std::vector<std::pair<int, int>> v; int k;   return std::count_if(v.begin(), v.end(), check2nd(k));   // 自前ループ   std::vector<std::pair<int, int>> v; int k;   int result = 0;   for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result;   return result;
lambda (無名関数オブジェクト) <algorithm>は便利だけど関数オブジェクト書くのが  面倒でループで書いてしまう↓ その場で関数オブジェクトが書ける スコープ内の変数を参照可能   // lambda   vector<std::pair<int, int>> v; int k;   return std::count_if(v.begin(), v.end(),            [&](const std::pair<int, int>& p) { return p.second == k; }); 中身が return だけなら戻り値の型を省略可能   [&](const std::pair<int, int>& p) -> bool { return p.second == k; } [&] はスコープ内変数の参照の仕方の指定
lambda (関数内関数風) ヘルパ関数として切り出したいけど状態渡すのが面倒 int count2nd(const std::vector<std::pair<int, int>> &v, int k) {     int result = 0;     for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result;     return result; } std::vector<std::pair<int, int>> v; if(count2nd(v, 0) == 0 && count2nd(v, 1) == v.size()) /* 適当 */ マクロは C++er として認められないし グローバル変数は未初期化とか上書きの問題がある
lambda (関数内関数風) ヘルパ関数として切り出したいけど状態渡すのが面倒 int count2nd(const std::vector<std::pair<int, int>> &v, int k) {     int result = 0;     for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result;     return result; } std::vector<std::pair<int, int>> v; if(count2nd(v, 0) == 0 && count2nd(v, 1) == v.size()) /* 適当 */ 関数内関数的にその場でヘルパ関数を定義できる std::vector<std::pair<int, int>> v; auto count2nd = [&] (int k) -> int {     int result = 0;     for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result;     return result; }; if(count2nd(0) == 0 && count2nd(1) == v.size()) /* 適当 */
lambda (関数内関数風) ヘルパ関数として切り出したいけど状態渡すのが面倒 int count2nd(const std::vector<std::pair<int, int>> &v, int k) {    int result = 0;    for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result;    return result; } std::vector<std::pair<int, int>> v; If(count2nd(v, 0) == 0 && count2nd(v, 1) == v.size()) /* 適当 */ 関数内関数的にその場でヘルパ関数を定義できる ※内部でも lambda を使った場合 std::vector<std::pair<int, int>> v; auto count2nd = [&] (int k) {     return count_if(v.begin(), v.end(),              [&] (const std::pair<int, int>&p) { return p.second == k; }); }; if(count2nd(0) == 0 && count2nd(1) == v.size()) /* 適当 */
lambda (関数内関数風) 応用編   再帰関数を定義したい → std::function と組み合わせ   std::vector<std::vector<int>> adj; int goal;   std::vector<bool> visited(adj.size());   // auto dfs = … だとエラーが出る   std::function<bool(int)> dfs = [&](int n) -> bool {       if(n == goal) return true;       visited[n] = true;       for(int i: adj[n]) {          if(!visited[i]) {              bool res = dfs(i);              if(res) return true;          }       }       return false;   };※std::funciton は関数オブジェクトも持てる関数ポインタ的イメージ
tuple いちいち構造体を宣言し、かつ比較演算子を  用意するのがかったるい  struct data { int level, value, cost; };  bool operator<(const data& d1, const data &d2){     return d1.level < d2.level    || d1.level == d2.level && d1.value < d2.value    || d1.level == d2.level && d1.value == d2.value && d1.cost < d2.cost;  }  std::set<data> s; tuple にお任せ  typedef std::tuple<int, int, int> data; // 辞書式比較演算子定義済み  std::set<data> s;  // こういう用意をしておくてアクセスが分かりやすいかも  enum { LEVEL, VALUE, COST };  std::get<LEVEL>(*s.begin());  ref. http://topcoder.g.hatena.ne.jp/cafelier/20110816/1313498443
initializer_list vector とかの内容を自由に初期化する方法がない   std::vector<int> v(5);   int init[5] = { 1, 3, 2, 5, 4 };   std::copy(init, init + 5, v.begin());  →初期化リスト(initializer_list)をとるコンストラクタを定義できる   std::vector<int> v({1, 3, 2, 5, 4});   // コンストラクタ呼び出しは () じゃなくて {} でもできるようになったので   // 以下も OK   std::vector<int> v{1, 3, 2, 5, 4};  map だって初期化できる   std::map<std::string, int> v = {      { "first", 1 },      { "second", 2 }   };
initializer_list 応用編  min / max   min / max は 2 引数だったので複数値の min / max   をとりたい場合は多段で適用する必要があった   int minimum = std::min(std::min(a, b), std::min(c, d));   →initializer_list を受けられるようになったので一発で OK   int minimum = std::min({a, b, c, d});
initializer_list 応用編  固定値のリストでループ   固定値を持つ配列を用意して添え字でループ   int init[] = { 1, 2, 3, 5, 8, 13, 21 };   for(std::size_t i = 0; i < sizeof(init) / sizeof(init[0]); ++i) {      std::cout << init[i] << std::endl;   }   →Range-based for と initializer_list の組み合わせで   こんな簡潔に   for(int i : { 1, 2, 3, 5, 8, 13, 21} ) {      std::cout << i << std::endl;   }
unordered_map / unordered_set map / set はあるけど計算量が O(log n)  std::set<int> s;  s.insert(5); // 挿入 O(log n)  s.erase(5); // 削除 O(log n)  s.count(3); // 検索 O(log n) →いわゆるハッシュテーブルとして unordered_map / unordered_set が導入 ※hash_map / hash_set だと既存実装とぶつかるので別名で導入  std::unordered_set<int> s;  s.insert(5); // 挿入 O(1)  s.erase(5); // 削除 O(1)  s.count(3); // 検索 O(1)  // トレードオフはメモリ使用量
新規アルゴリズム(iota)インデックス用配列の初期化めんどい  std::vector<int> vdata;  std::vector<int> index(vdata.size());  for(std::size_t i = 0; i < index.size(); ++i) index[i] = i;  std::sort(index.begin(), index.end(),              [&](int n1, int n2) { return vdata[n1] < vdata[n2]; });  for(int i: index) { std::cout << i << " : " << vdata[i] << std::endl; } →地味に仕事をする std::iota  std::vector<int> vdata;  std::vector<int> index(vdata.size());  std::iota(index.begin(), index.end(), 0); // 0 が初期値で 0, 1, 2, …  std::sort(index.begin(), index.end(),              [&](int n1, int n2) { return vdata[n1] < vdata[n2]; });  for(int i: index) { std::cout << i << " : " << vdata[i] << std::endl; } #define RNG(c) (c).begin(), (c).end() でさらに便利
新規アルゴリズム(*_of)→all_of / any_of / none_of 名前通り   std::vector<int> v;   if(std::all_of(v.begin(), v.end(), [](int n){ return n >= 5; })) {       /* 全要素 5 以上の場合 */   }   if(std::any_of(v.begin(), v.end(), [](int n){ return n >= 5; })) {       /* どれか1要素でも 5 以上の場合 */   }   if(std::none_of(v.begin(), v.end(), [](int n){ return n >= 5; })) {       /* 5 以上の要素がない場合 */   }
ちょっとした改善(map::at)map::operator[] のせいで const 性の維持が 面倒  int get(const std::map<std::string, int> &m, const std::string &s)  {  // map::operator[] に const 版はないのでこう書けない  // return m[s];     return m.find(s)->second;  } →const 版のある at() で OK  int get(const std::map<std::string, int> &m, const std::string &s)  {     return m.at(s);  }
対応微妙(regex, emplace)→regex(正規表現)で文字列処理が容易に! ※でも gcc(libstdc++) は対応微妙→emplace で insert 時等の生成を省略 ※でも gcc(libstdc++) はコンテナ毎に対応微妙  std::vector<pair<std::string, int>> v;  v.push_back(std::make_pair(std::string("hoge"), 5)); ※直接、挿入する場所に値を生成するイメージ  std::vector<pair<std::string, int>> v;  v.emplace_back("hoge", 5);
まとめ今なら Codeforces でも C++0x 使用者は 尐ないので 「同一言語使用者内で世界10位以内(キリッ」 とか言えるC++0x は大変便利なので 競技プログラミングでもばりばり使うべき
参考文献競技プログラマのためのC++0xB http://topcoder.g.hatena.ne.jp/cafelier/201 10816/1313498443Wikipedia C++0x http://ja.wikipedia.org/wiki/C%2B%2B0xcpprefjp https://sites.google.com/site/cpprefjp/
ご清聴ありがとうございました。

Recommended

PPTX
Map
PPTX
競技プログラミングのためのC++入門
PDF
競技プログラミングにおけるコードの書き方とその利便性
PDF
C++ ポインタ ブートキャンプ
PPT
C++0x in programming competition
 
PPTX
ぱっと見でわかるC++11
PDF
怠惰なRubyistへの道 fukuoka rubykaigi01
PDF
C++0x 言語の未来を語る
PDF
クロージャデザインパターン
PPTX
函数プログラミングの エッセンスと考え方
PDF
ゲーム開発者のための C++11/C++14
PDF
Replace Output Iterator and Extend Range JP
PDF
C++11概要 ライブラリ編
 
PDF
Emcpp item31
PDF
Boost.Coroutine
 
ODP
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
PPTX
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
PDF
Effective Modern C++ 読書会 Item 35
PDF
すごいConstたのしく使おう!
PPTX
Effective modern C++ 勉強会 #3 Item 12
PPTX
Brief introduction of Boost.ICL
 
PDF
わんくま同盟大阪勉強会#61
ODP
Ekmett勉強会発表資料
PPTX
C#6.0の新機能紹介
PDF
emc++ chapter32
PDF
Emcjp item21
PDF
What is template
PDF
C++入門?
 
PDF
F#入門 ~関数プログラミングとは何か~
PDF
Pfi Seminar 2010 1 7

More Related Content

PPTX
Map
PPTX
競技プログラミングのためのC++入門
PDF
競技プログラミングにおけるコードの書き方とその利便性
PDF
C++ ポインタ ブートキャンプ
PPT
C++0x in programming competition
 
PPTX
ぱっと見でわかるC++11
PDF
怠惰なRubyistへの道 fukuoka rubykaigi01
PDF
C++0x 言語の未来を語る
Map
競技プログラミングのためのC++入門
競技プログラミングにおけるコードの書き方とその利便性
C++ ポインタ ブートキャンプ
C++0x in programming competition
 
ぱっと見でわかるC++11
怠惰なRubyistへの道 fukuoka rubykaigi01
C++0x 言語の未来を語る

What's hot

PDF
クロージャデザインパターン
PPTX
函数プログラミングの エッセンスと考え方
PDF
ゲーム開発者のための C++11/C++14
PDF
Replace Output Iterator and Extend Range JP
PDF
C++11概要 ライブラリ編
 
PDF
Emcpp item31
PDF
Boost.Coroutine
 
ODP
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
PPTX
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
PDF
Effective Modern C++ 読書会 Item 35
PDF
すごいConstたのしく使おう!
PPTX
Effective modern C++ 勉強会 #3 Item 12
PPTX
Brief introduction of Boost.ICL
 
PDF
わんくま同盟大阪勉強会#61
ODP
Ekmett勉強会発表資料
PPTX
C#6.0の新機能紹介
PDF
emc++ chapter32
PDF
Emcjp item21
PDF
What is template
PDF
C++入門?
 
クロージャデザインパターン
函数プログラミングの エッセンスと考え方
ゲーム開発者のための C++11/C++14
Replace Output Iterator and Extend Range JP
C++11概要 ライブラリ編
 
Emcpp item31
Boost.Coroutine
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
Effective Modern C++ 読書会 Item 35
すごいConstたのしく使おう!
Effective modern C++ 勉強会 #3 Item 12
Brief introduction of Boost.ICL
 
わんくま同盟大阪勉強会#61
Ekmett勉強会発表資料
C#6.0の新機能紹介
emc++ chapter32
Emcjp item21
What is template
C++入門?
 

Similar to C++0x in programming competition

PDF
F#入門 ~関数プログラミングとは何か~
PDF
Pfi Seminar 2010 1 7
PDF
C++コミュニティーの中心でC++をDISる
PDF
Boost Tour 1.50.0 All
PDF
Boost.Flyweight
PDF
動的計画法入門(An introduction to Dynamic Programming)
PDF
C++11のつかいかた
PDF
関数プログラミング入門
PDF
関数型プログラミング入門 with OCaml
KEY
Algebraic DP: 動的計画法を書きやすく
PDF
Constexpr 中3女子テクニック
PPTX
純粋関数型アルゴリズム入門
PPTX
Cranberries interval library 開発の話
PDF
boost tour 1.48.0 all
PDF
Boost tour 1_40_0
PDF
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
PDF
Iterators must-go(ja)
PDF
programming camp 2008, introduction of programming, algorithm
F#入門 ~関数プログラミングとは何か~
Pfi Seminar 2010 1 7
C++コミュニティーの中心でC++をDISる
Boost Tour 1.50.0 All
Boost.Flyweight
動的計画法入門(An introduction to Dynamic Programming)
C++11のつかいかた
関数プログラミング入門
関数型プログラミング入門 with OCaml
Algebraic DP: 動的計画法を書きやすく
Constexpr 中3女子テクニック
純粋関数型アルゴリズム入門
Cranberries interval library 開発の話
boost tour 1.48.0 all
Boost tour 1_40_0
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Iterators must-go(ja)
programming camp 2008, introduction of programming, algorithm

More from yak1ex

PPT
Introduction to programming competition [revised]
 
PPT
Introduction to programming competition
 
PDF
Brief introduction of Boost.ICL [PDF]
 
PPT
Impractical Introduction of Boost Spirit Qi [PPT]
 
PDF
GC in C++0x [eng]
 
PDF
GC in C++0x
 
PDF
Introduction to programming competition [revised][PDF]
 
PDF
Brief introduction of Boost.ICL
 
Introduction to programming competition [revised]
 
Introduction to programming competition
 
Brief introduction of Boost.ICL [PDF]
 
Impractical Introduction of Boost Spirit Qi [PPT]
 
GC in C++0x [eng]
 
GC in C++0x
 
Introduction to programming competition [revised][PDF]
 
Brief introduction of Boost.ICL
 

C++0x in programming competition

  • 1.
    競技プログラミングからみたC++0x OSC名古屋2011 8/20(土) はじめての競技プログラミング 蛇足 @yak_ex / 新 康孝 (CSNagoya)
  • 2.
    自己紹介 氏名: 新康孝 (あたらし やすたか) Twitter ID: yak_ex Web: http://yak3.myhome.cx:8080/junks C++ / Perl が主戦場 現在、仕事でコードに触れていないので 競技プログラミング(TopCoder、Codeforces)で 潤い補充 闇の軍団に憧れるただの C++ 好き
  • 3.
    C++0x とは 国際標準化機構ISO で規格化されている C++ 規格(ISO 14882)の次期版仮称  200x 年代に発行予定だったが間に合わなかったため 0x は 16 進プ レフィクスということに http://www2.research.att.com/~bs/C++0xFAQ.html 先頃 Final Draft が承認され規格発行を待つ状態であり正 式名称 14882:2011 となる予定 小修正だった 14882:2003 とは異なり、言語自体また標準ラ イブラリに非常に大きな変更が加えられている 本稿では競技プログラミングから見た C++0x の利点につい て紹介する  Codeforces で gcc 4.6 での C++0x 機能が使えるのでそれを基準と して説明する
  • 4.
    目次 auto Range-basedfor Lambda tuple initializer_list unordered_map / unordered_set 新規アルゴリズム (iota, all_of) ちょっとした改善 (map::at) 対応微妙(regex / emplace)
  • 5.
    auto 例えば setの要素についてループする場合、 Iterator の型を書くのが面倒 set<int> s; for(set<int>::iterator it = s.begin(); it != s.end(); ++it) { if(*it == 5) it = s.erase(it); } →auto にしておけばコンパイラが型を導出してくれる set<int> s; for(auto it = s.begin(); it != s.end(); ++it) { if(*it == 5) it = s.erase(it); }
  • 6.
    Range-based for 例えば単純にset の要素についてループする場合、 C++03では色々と面倒 std::set<int> s; for(std::set<int>::iterator it = s.begin(); it != s.end(); ++it) std::cout << *it << std::endl; auto でもやっぱり微妙 std::set<int> s; for(auto it = s.begin(); it != s.end(); ++it) std::cout << *it << std::endl; Range-based for ループですっきり set<int> s; for(auto v : s) std::cout << v << std::endl; コンテナ s の各要素を v に割り当ててループ
  • 7.
    lambda (無名関数オブジェクト) <algorithm>は便利だけど関数オブジェクト書くのが 面倒でループで書いてしまう // 関数オブジェクト struct check2nd { check2nd(const int &n) : n(n) {} bool operator()(const std::pair<int, int> &p) { return p.second == n; } const int &n; }; std::vector<std::pair<int, int>> v; int k; return std::count_if(v.begin(), v.end(), check2nd(k)); // 自前ループ std::vector<std::pair<int, int>> v; int k; int result = 0; for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result; return result;
  • 8.
    lambda (無名関数オブジェクト) <algorithm>は便利だけど関数オブジェクト書くのが 面倒でループで書いてしまう↓ その場で関数オブジェクトが書ける スコープ内の変数を参照可能 // lambda vector<std::pair<int, int>> v; int k; return std::count_if(v.begin(), v.end(), [&](const std::pair<int, int>& p) { return p.second == k; }); 中身が return だけなら戻り値の型を省略可能 [&](const std::pair<int, int>& p) -> bool { return p.second == k; } [&] はスコープ内変数の参照の仕方の指定
  • 9.
    lambda (関数内関数風) ヘルパ関数として切り出したいけど状態渡すのが面倒int count2nd(const std::vector<std::pair<int, int>> &v, int k) { int result = 0; for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result; return result; } std::vector<std::pair<int, int>> v; if(count2nd(v, 0) == 0 && count2nd(v, 1) == v.size()) /* 適当 */ マクロは C++er として認められないし グローバル変数は未初期化とか上書きの問題がある
  • 10.
    lambda (関数内関数風) ヘルパ関数として切り出したいけど状態渡すのが面倒int count2nd(const std::vector<std::pair<int, int>> &v, int k) { int result = 0; for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result; return result; } std::vector<std::pair<int, int>> v; if(count2nd(v, 0) == 0 && count2nd(v, 1) == v.size()) /* 適当 */ 関数内関数的にその場でヘルパ関数を定義できる std::vector<std::pair<int, int>> v; auto count2nd = [&] (int k) -> int { int result = 0; for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result; return result; }; if(count2nd(0) == 0 && count2nd(1) == v.size()) /* 適当 */
  • 11.
    lambda (関数内関数風) ヘルパ関数として切り出したいけど状態渡すのが面倒int count2nd(const std::vector<std::pair<int, int>> &v, int k) { int result = 0; for(int i=0;i<v.size(); ++i) if(v[i].second == k) ++result; return result; } std::vector<std::pair<int, int>> v; If(count2nd(v, 0) == 0 && count2nd(v, 1) == v.size()) /* 適当 */ 関数内関数的にその場でヘルパ関数を定義できる ※内部でも lambda を使った場合 std::vector<std::pair<int, int>> v; auto count2nd = [&] (int k) { return count_if(v.begin(), v.end(), [&] (const std::pair<int, int>&p) { return p.second == k; }); }; if(count2nd(0) == 0 && count2nd(1) == v.size()) /* 適当 */
  • 12.
    lambda (関数内関数風) 応用編 再帰関数を定義したい → std::function と組み合わせ std::vector<std::vector<int>> adj; int goal; std::vector<bool> visited(adj.size()); // auto dfs = … だとエラーが出る std::function<bool(int)> dfs = [&](int n) -> bool { if(n == goal) return true; visited[n] = true; for(int i: adj[n]) { if(!visited[i]) { bool res = dfs(i); if(res) return true; } } return false; };※std::funciton は関数オブジェクトも持てる関数ポインタ的イメージ
  • 13.
    tuple いちいち構造体を宣言し、かつ比較演算子を用意するのがかったるい struct data { int level, value, cost; }; bool operator<(const data& d1, const data &d2){ return d1.level < d2.level || d1.level == d2.level && d1.value < d2.value || d1.level == d2.level && d1.value == d2.value && d1.cost < d2.cost; } std::set<data> s; tuple にお任せ typedef std::tuple<int, int, int> data; // 辞書式比較演算子定義済み std::set<data> s; // こういう用意をしておくてアクセスが分かりやすいかも enum { LEVEL, VALUE, COST }; std::get<LEVEL>(*s.begin()); ref. http://topcoder.g.hatena.ne.jp/cafelier/20110816/1313498443
  • 14.
    initializer_list vector とかの内容を自由に初期化する方法がない std::vector<int> v(5); int init[5] = { 1, 3, 2, 5, 4 }; std::copy(init, init + 5, v.begin()); →初期化リスト(initializer_list)をとるコンストラクタを定義できる std::vector<int> v({1, 3, 2, 5, 4}); // コンストラクタ呼び出しは () じゃなくて {} でもできるようになったので // 以下も OK std::vector<int> v{1, 3, 2, 5, 4}; map だって初期化できる std::map<std::string, int> v = { { "first", 1 }, { "second", 2 } };
  • 15.
    initializer_list 応用編min / max min / max は 2 引数だったので複数値の min / max をとりたい場合は多段で適用する必要があった int minimum = std::min(std::min(a, b), std::min(c, d)); →initializer_list を受けられるようになったので一発で OK int minimum = std::min({a, b, c, d});
  • 16.
    initializer_list 応用編固定値のリストでループ 固定値を持つ配列を用意して添え字でループ int init[] = { 1, 2, 3, 5, 8, 13, 21 }; for(std::size_t i = 0; i < sizeof(init) / sizeof(init[0]); ++i) { std::cout << init[i] << std::endl; } →Range-based for と initializer_list の組み合わせで こんな簡潔に for(int i : { 1, 2, 3, 5, 8, 13, 21} ) { std::cout << i << std::endl; }
  • 17.
    unordered_map / unordered_setmap / set はあるけど計算量が O(log n) std::set<int> s; s.insert(5); // 挿入 O(log n) s.erase(5); // 削除 O(log n) s.count(3); // 検索 O(log n) →いわゆるハッシュテーブルとして unordered_map / unordered_set が導入 ※hash_map / hash_set だと既存実装とぶつかるので別名で導入 std::unordered_set<int> s; s.insert(5); // 挿入 O(1) s.erase(5); // 削除 O(1) s.count(3); // 検索 O(1) // トレードオフはメモリ使用量
  • 18.
    新規アルゴリズム(iota)インデックス用配列の初期化めんどい std::vector<int>vdata; std::vector<int> index(vdata.size()); for(std::size_t i = 0; i < index.size(); ++i) index[i] = i; std::sort(index.begin(), index.end(), [&](int n1, int n2) { return vdata[n1] < vdata[n2]; }); for(int i: index) { std::cout << i << " : " << vdata[i] << std::endl; } →地味に仕事をする std::iota std::vector<int> vdata; std::vector<int> index(vdata.size()); std::iota(index.begin(), index.end(), 0); // 0 が初期値で 0, 1, 2, … std::sort(index.begin(), index.end(), [&](int n1, int n2) { return vdata[n1] < vdata[n2]; }); for(int i: index) { std::cout << i << " : " << vdata[i] << std::endl; } #define RNG(c) (c).begin(), (c).end() でさらに便利
  • 19.
    新規アルゴリズム(*_of)→all_of / any_of/ none_of 名前通り std::vector<int> v; if(std::all_of(v.begin(), v.end(), [](int n){ return n >= 5; })) { /* 全要素 5 以上の場合 */ } if(std::any_of(v.begin(), v.end(), [](int n){ return n >= 5; })) { /* どれか1要素でも 5 以上の場合 */ } if(std::none_of(v.begin(), v.end(), [](int n){ return n >= 5; })) { /* 5 以上の要素がない場合 */ }
  • 20.
    ちょっとした改善(map::at)map::operator[] のせいで const性の維持が 面倒 int get(const std::map<std::string, int> &m, const std::string &s) { // map::operator[] に const 版はないのでこう書けない // return m[s]; return m.find(s)->second; } →const 版のある at() で OK int get(const std::map<std::string, int> &m, const std::string &s) { return m.at(s); }
  • 21.
    対応微妙(regex, emplace)→regex(正規表現)で文字列処理が容易に! ※でもgcc(libstdc++) は対応微妙→emplace で insert 時等の生成を省略 ※でも gcc(libstdc++) はコンテナ毎に対応微妙 std::vector<pair<std::string, int>> v; v.push_back(std::make_pair(std::string("hoge"), 5)); ※直接、挿入する場所に値を生成するイメージ std::vector<pair<std::string, int>> v; v.emplace_back("hoge", 5);
  • 22.
    まとめ今なら Codeforces でもC++0x 使用者は 尐ないので 「同一言語使用者内で世界10位以内(キリッ」 とか言えるC++0x は大変便利なので 競技プログラミングでもばりばり使うべき
  • 23.
    参考文献競技プログラマのためのC++0xB http://topcoder.g.hatena.ne.jp/cafelier/201 10816/1313498443WikipediaC++0x http://ja.wikipedia.org/wiki/C%2B%2B0xcpprefjp https://sites.google.com/site/cpprefjp/
  • 24.

[8]ページ先頭

©2009-2025 Movatter.jp