SlideShare ist ein Scribd-Unternehmen logo
1 von 24
Downloaden Sie, um offline zu lesen
競技プログラミングからみた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/
ご清聴ありがとうございました。

Weitere ähnliche Inhalte

Was ist angesagt?

すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!Akihiro Nishimura
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICLyak1ex
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編egtra
 
Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12Keisuke Fukuda
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61TATSUYA HAYAMIZU
 
C++入門?
C++入門?C++入門?
C++入門?tsudaa
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Keisuke Fukuda
 
函数プログラミングの エッセンスと考え方
函数プログラミングのエッセンスと考え方函数プログラミングのエッセンスと考え方
函数プログラミングの エッセンスと考え方啓 小笠原
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
Boost.Coroutine
Boost.CoroutineBoost.Coroutine
Boost.Coroutinemelpon
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜勝成 鈴江
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~Fujio Kojima
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 

Was ist angesagt? (20)

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

Ähnlich wie C++0x in programming competition

C++ lecture-1
C++ lecture-1C++ lecture-1
C++ lecture-1sunaemon
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)Akihiko Matuura
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Springanyakichi
 
Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Takefumi MIYOSHI
 
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519Yasuhiro Ishii
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsKohei KaiGai
 
2018/06/23 Sony"s deep learning software and the latest information
2018/06/23 Sony"s deep learning software and the latest information2018/06/23 Sony"s deep learning software and the latest information
2018/06/23 Sony"s deep learning software and the latest informationSony Network Communications Inc.
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013Ryo Sakamoto
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputingNoboru Irieda
 
Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)ryos36
 
C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)Akira Takahashi
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和schoowebcampus
 
復習と型 Jyoken
復習と型 Jyoken復習と型 Jyoken
復習と型 Jyokenreew2n
 

Ähnlich wie C++0x in programming competition (20)

C++ lecture-1
C++ lecture-1C++ lecture-1
C++ lecture-1
 
Slide
SlideSlide
Slide
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
初めてのSTL
初めてのSTL初めてのSTL
初めてのSTL
 
Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512
 
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
 
PL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database AnalyticsPL/CUDA - GPU Accelerated In-Database Analytics
PL/CUDA - GPU Accelerated In-Database Analytics
 
2018/06/23 Sony"s deep learning software and the latest information
2018/06/23 Sony"s deep learning software and the latest information2018/06/23 Sony"s deep learning software and the latest information
2018/06/23 Sony"s deep learning software and the latest information
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
 
Boost Tour 1.50.0
Boost Tour 1.50.0Boost Tour 1.50.0
Boost Tour 1.50.0
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)Polyphony の行く末(2018/3/3)
Polyphony の行く末(2018/3/3)
 
C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)
 
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
 
復習と型 Jyoken
復習と型 Jyoken復習と型 Jyoken
復習と型 Jyoken
 

Mehr von yak1ex

Introduction to programming competition [revised][PDF]
Introduction to programming competition [revised][PDF]Introduction to programming competition [revised][PDF]
Introduction to programming competition [revised][PDF]yak1ex
 
Introduction to programming competition [revised]
Introduction to programming competition [revised]Introduction to programming competition [revised]
Introduction to programming competition [revised]yak1ex
 
Introduction to programming competition
Introduction to programming competitionIntroduction to programming competition
Introduction to programming competitionyak1ex
 
Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]Impractical Introduction of Boost Spirit Qi [PPT]
Impractical Introduction of Boost Spirit Qi [PPT]yak1ex
 
Brief introduction of Boost.ICL [PDF]
Brief introduction of Boost.ICL [PDF]Brief introduction of Boost.ICL [PDF]
Brief introduction of Boost.ICL [PDF]yak1ex
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICLyak1ex
 
GC in C++0x [eng]
GC in C++0x [eng]GC in C++0x [eng]
GC in C++0x [eng]yak1ex
 
GC in C++0x
GC in C++0xGC in C++0x
GC in C++0xyak1ex
 

Mehr von yak1ex (8)

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

Kürzlich hochgeladen

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 

Kürzlich hochgeladen (10)

Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 

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-based for  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 Wikipedia C++0x http://ja.wikipedia.org/wiki/C%2B%2B0x cpprefjp https://sites.google.com/site/cpprefjp/