競技プログラミングのためのC++入門

競技プログラミングのための
    C++入門
   @natrium11321
C++ って何?

• C言語の進化系(の一つ)

                      C++
                •   オブジェクト指向
       C言語      •   参照型
                •   例外機構
  •   配列        •   演算子オーバーロード
  •   関数        •   実行時型情報
  •   ポインタ      •   テンプレート
                •   STL
  •   構造体
                •   スレッド (C++11より)
                •   型推論
                •   ラムダ式
C++ って何?

• C言語の進化系(の一つ)

                   C++
   使えると      •   オブジェクト指向
     C言語     •   参照型
 競技でめっちゃ     •   例外機構
  • 配列
  便利!!!      •   演算子オーバーロード
  • 関数       •   実行時型情報
  • ポインタ     •   テンプレート
             •   STL
  • 構造体
             •   スレッド (C++11より)
             •   型推論
             •   ラムダ式
C++ことはじめ
           C++を入門します
C++ことはじめ

• C言語の Hello, world!
   hello.c
    #include <stdio.h>

    int main(void)
    {
        printf(‚Hello, world!n‛);
        return 0;
    }
C++ことはじめ

• C++の Hello, world!
   hello.cpp
    #include <cstdio>
    using namespace std;

    int main()
    {
        printf(‚Hello, world!n‛);
        return 0;
    }



                      本当はC言語版のコードもそのまま動くが…
CとC++の違い
hello.c
 #include <stdio.h>

 int main(void)
 {
     printf(‚Hello, world!n‛);
     return 0;
 }                   !?
hello.cpp
 #include <cstdio>
 using namespace std;

 int main()
 {
     printf(‚Hello, world!n‛);
     return 0;
 }
CとC++の違い ①拡張子

• C言語では       • C++では
 – test.c       – test.cpp
 – hoge.c       – hoge.cpp
CとC++の違い
hello.c
 #include <stdio.h>

 int main(void)
 {
     printf(‚Hello, world!n‛);
     return 0;
 }
                                  !?!?
hello.cpp
 #include <cstdio>
 using namespace std;

 int main()
 {
     printf(‚Hello, world!n‛);
     return 0;
 }
CとC++の違い ②ヘッダ名

• C言語では              • C++では
 –   stdio.h            –   cstdio
 –   stdlib.h           –   cstdlib
 –   math.h             –   cmath
 –   string.h           –   cstring
 –   ctype.h            –   cctype


     cstdio:「C言語の時からあるstdioという名前のヘッダ」
                     ↓
        C++で新たに追加されたヘッダには ’c’ は付かない
CとC++の違い
hello.c
 #include <stdio.h>

 int main(void)
 {
     printf(‚Hello, world!n‛);
     return 0;
 }

hello.cpp
 #include <cstdio>
 using namespace std;
                             ☆おまじない☆
                             !?!??!
 int main()
 {
     printf(‚Hello, world!n‛);
     return 0;
 }
CとC++の違い
hello.c
 #include <stdio.h>

 int main(void)
 {
     printf(‚Hello, world!n‛);
     return 0;
 }

hello.cpp
 #include <cstdio>
 using namespace std;
                             !?!??!!?
 int main()
 {
     printf(‚Hello, world!n‛);
     return 0;
 }
CとC++の違い ③引数のvoid
void.c                       void.cpp

 #include <stdio.h>           #include <cstdio>
                              using namespace std;
 void func(void);             void func();
 int main(void)               int main()
 {                            {
     func();                      func();
     return 0;                    return 0;
 }                            }
 void func(void)              void func()
 {                            {
     printf(‚fugafugan‛);        printf(‚fugafugan‛);
 }                            }


• C++では引数のvoidを省略可
  – 引数のみ
もうひとつ!
 One more!
CとC++の違い ④構造体

• C言語の構造体
  structure.c
   struct Human
   {
       int age;
       double weight;
       char name[256];
   };

   int main(void)
   {
       struct Human taro;
       taro.age = 21;
       …
   }
CとC++の違い ④構造体

• C言語の構造体 (typedef)
  structure.c
   typedef struct
   {
       int age;
       double weight;
       char name[256];
   } Human;

   int main(void)
   {
       Human taro;
       taro.age = 21;
       …
   }
CとC++の違い ④構造体

• C++の構造体
  structure.cpp
   struct Human
   {
       int age;
       double weight;
       char name[256];
   };

   int main()
   {
       Human taro;
       taro.age = 21;
       …
   }
C++新機能紹介
           boolと変数の宣言位置
C++新機能 ①bool
eratos.c
 /*
  * n以下のxについて isprime[x] == 1 だったらxは素数
  * という配列isprimeを作る
  */
 void make_sieve(int n, int isprime[])
 {
     int i, j;
     isprime[0] = isprime[1] = 0;
     for(i=2; i<=n; ++i)
         isprime[i] = 1;

      for(i=2; i<=n; ++i){
          if(isprime[i] == 1){
              for(j=i*2; j<=n; j+=i)
                  isprime[j] = 0;
          }
      }
 }
C++新機能 ①bool
              2,147,483,647まで格納できるintに
( ^o^)       0か1しか格納しないのは勿体無いな…



                   待てよ、書いてたコード
( ˘⊖˘)               C++だっけ…



( ◠‿◠ )☛       そこに気づいてしまったか…
              貴様にはbool型を使ってもらおう


▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂
    うわあああああああ
C++新機能 ①bool
• bool型変数(1bit整数)
  bool flag;


• 値は true(真) か false(偽) を代入
  flag = true;    // 数値としては1
  flag = false;   // 数値としては0


• if で使う
  if(flag){
      puts(‚flag is true‛);
  }
  else{
      puts(‚flag is false‛);
  }
C++新機能 ①bool
• 比較の結果を格納
 int a = 3, b = 5;
 flag = a < b;   // true
 flag = a != b; // true
 flag = a >= b; // false


• 否定演算
 bool flag1 = true;
 bool flag2 = !flag1; // false
 bool flag3 = !flag2; // true
 if(!flag){
     puts(‚flag is false‛);
 }
 else{
     puts(‚flag is true‛);
 }
C++新機能 ①bool
eratos.cpp
 // n以下のxについて isprime[x] がtrueだったらxは素数
 // という配列isprimeを作る
 void make_sieve(int n, bool isprime[])
 {
     int i, j;
     isprime[0] = isprime[1] = false;
     for(i=2; i<=n; ++i)
         isprime[i] = true;

      for(i=2; i<=n; ++i){
          if(isprime[i]){
              for(j=i*2; j<=n; j+=i)
                  isprime[j] = false;
          }
      }
 }
C++新機能 ①bool
• bool を使うメリット
  int flag;     bool flag;
    「これはフラグを表す変数です」
     というのが分かりやすい

  flag = 1;     flag = true;
     0や1といった怪しい数字で
      場合分けしなくて良い
  int : 4バイト       bool : 1バイト

     メモリを節約できる
C++新機能 ②変数の宣言位置
gucha.c
 /* プログラム速いけど微妙にバグる */
 int main(void)
 {
     int i, j, k, n, a[1024];
     int map[1024][1024];
     int from, to, end, *p, *q;
     char c, s, t, str[128];
     …
 }


               \(^o^)/

          どの変数をどこで使ってるかが分からん!
C++新機能 ②変数の宣言位置
smart.cpp
                                                   ここだけ
 int main() {
     int n;                                        じゃなく
     scanf(‚%d‛, &n);

     int a[1024];                                  ここでも
     for(int i=0; i<n; ++i)
         scanf(‚%d‛, &a[i]);

     int map[1024][1024];
                                                   ここでも
     for(int i=0; i<n; ++i){
         for(int j=0; j<n; ++j){
             map[i][j] = 0;                        ここでも
             for(int k=0; k<n; ++k)
                 map[i][j] += a[i] * a[(j+k)%n];
         }
     }
     …
                                                   この辺でも
 }
C++新機能 ②変数の宣言位置
• どこでも変数宣言が出来る
 – 特にforの中でのループ変数の宣言は便利


• どこでも変数宣言が出来るメリット
  変数を使う直前に宣言できる
    どこで変数を使ってるかが分かりやすい!
    宣言部分がごちゃごちゃしない!
    初期化を忘れない!
C++新機能 ②変数の宣言位置
eratos_smart.cpp
 // n以下のxについて isprime[x] がtrueだったらxは素数
 // という配列isprimeを作る
 void make_sieve(int n, bool isprime[])
 {
     isprime[0] = isprime[1] = false;
     for(int i=2; i<=n; ++i)
         isprime[i] = true;

      for(int i=2; i<=n; ++i){
          if(isprime[i]){
              for(int j=i*2; j<=n; j+=i)
                  isprime[j] = false;
          }
      }
 }
STL (Standard Template Library)
                  algorithm, stack, queue, string
STLって何?

• C++の標準ライブラリ(の一部)

• とても便利な機能が沢山詰まってます
 – 特に競技プログラミングでは重宝


• 本日紹介するのは
 –   <algorithm>
 –   <stack>
 –   <queue>
 –   <string>
algorithm

• 便利な関数の詰め合わせセット
  #include <algorithm>
  using namespace std;




• 基本的にSTLの関数は引数の型について不問
 – 「テンプレート」で実現
 – 今日は詳しくやりません
最大値・最小値

• min(a, b)
  – aとbの小さい方の値を返す
• max(a, b)
  – aとbの大きい方の値を返す

    int a = 10, b = 4;

    int small = min(a, b);      // 4
    int large = max(a, b);      // 10

    double c = 1.2, d = 5.8;
    double e = max(c*c, d*d);   // int 以外もOK

    double f = min(a, c);         // 違う型を渡すとエラー
    double g = min((double)a, c); // キャストすればOK
交換

• swap(a, b)
  – aとb の値を交換する
    int a = 10, b = 4;
    printf(‚a is %d, b is %dn‛, a, b); // a is 10, b is 4

    swap(a, b);
    printf(‚a is %d, b is %dn‛, a, b); // a is 4, b is 10

    int* p = &a;
    int* q = &b;
    swap(p, q);
    *q += 3;
    printf(‚a is %d, b is %dn‛, a, b); // a is 7, b is 10
ソーティング

• sort(f, t)
  – f から t-1 までを昇順にソートする
  – f と t は配列のポインタ
  – 時間計算量 O(nlogn)

    int a[] = {5, 3, 7, 8, 2};
    sort(a, a+5);
    for(int i=0; i<5; ++i)
        printf(‚%d ‚, a[i]);

    /*
     * 出力結果
     * 2 3 5 7 8
     */
ソーティング

• reverse(f, t)
  – f から t-1 までを反転させる
  – 降順にソートしたければこれを使う
  – 時間計算量 O(n)

    int a[] = {5, 3, 7, 8, 2};
    reverse(a, a+5); // a = {2, 8, 7, 3, 5}

    sort(a, a+5);    // a = {2, 3, 5, 7, 8}
    reverse(a, a+5); // a = {8, 7, 5, 3, 2}
数え上げ

• count(f, t, x)
  – f から t-1 までに含まれるxの数を返す

    int a[] = {1, 4, 8, 2, 8, 6, 8, 1};
    int cnt8 = count(a, a+8, 8); // 3
    int cnt4 = count(a, a+8, 4); // 1



  – この関数のせいで ‚count‛ という名前の変数を作
    るとエラーが起こる
     • ‚cnt‛ とかで代用
初期化

• fill(f, t, x)
  – f から t-1 までを全て x で初期化する

    int a[] = {1, 4, 8, 2, 8, 6, 8, 1};
    fill(a, a+8, 1);   // a = {1, 1, 1, 1, 1, 1, 1, 1}
    fill(a+2, a+5, 8); // a = {1, 1, 8, 8, 8, 1, 1, 1}

    bool flags[1000];
    fill(flags, flags+1000, true);
algorithm

• ほかにも便利な関数いろいろ
 – equal, find, search, copy, remove, replace,

  random_shuffle, unique, lower_bound, upper_
  bound, binary_search, max_element, min_elem
  ent, next_permutation, etc…


    これらを知らないと猛烈に不利ということはない!
 (ループ回せば普通にできる、JOI予選程度では使わない、等)
stack/queue
• スタックとキュー



                         8
       8                 3
       3


     stack           queue
    (先入れ後出し)        (先入れ先出し)
stack/queue
• スタックとキュー
  #include <stack>
  #include <queue>
  using namespace std;
そのまえに
 Before it
クラスって何?

• C言語の構造体に毛が生えたもの

• 変数だけではなく、関数も中に入れられる
 – C++では構造体の中にも関数作れるけどね


• クラスの中の変数:メンバ変数
• クラスの中の関数:メンバ関数

• 使うだけなら簡単です
stack
• スタックの宣言
  stack<int> S;




      stack<int> というクラス(型)の、
       Sという名前の変数       を作成(インスタンス)




           int はスタックに格納する
               変数の型を表す
stack
• スタックへの追加
  stack<int> S;
  S.push(3);              S.push(x)
  S.push(5);               Sにxを追加
  S.push(-2);




                    -2
                    5
                    3
stack
• スタックの先頭要素の取り出し
 stack<int> S;
 S.push(3);                         S.top()
 S.push(5);                      現在のSの先頭要素を返す
 S.push(-2);                       (削除はしない)
 printf(‚%dn‛, S.top());
 S.pop();
 printf(‚%dn‛, S.top());           S.pop()
 S.pop();                        現在のSの先頭要素を削除
 S.push(20);



                            20
                            3
stack
• スタックのサイズ確認
  stack<int> S;
  S.push(3);
  S.push(5);                      S.size()
  S.push(-2);                   Sに含まれる要素数を返す

  int cnt = S.size();
  bool isempty = S.empty();       S.empty()
                                 Sが空かどうかを返す
  // スタックの全ての要素を取り出して表示
  while(!S.empty()){
      int data = S.top();
      S.pop();
      printf(‚%dn‛, data);
  }
queue
• キューの宣言・追加・先頭要素の取り出し
 queue<int> Q;
 Q.push(3);                     Q.push(x)
 Q.push(5);                      Qにxを追加
 Q.push(-2);
 printf(‚%dn‛, Q.front());
 Q.pop();                       Q.front()
 printf(‚%dn‛, Q.front());   現在のQの先頭要素を返す
 Q.pop();                       (削除はしない)
 Q.push(20);
                                 Q.pop()
                              現在のQの先頭要素を削除
            20
            -2
queue
• キューのサイズ確認
  queue<int> Q;
  Q.push(3);
  Q.push(5);                     Q.size()
  Q.push(-2);                  Qに含まれる要素数を返す

  int cnt = Q.size();
  bool isempty = Q.empty();      Q.empty()
                                Qが空かどうかを返す
  // キューの全ての要素を取り出して表示
  while(!Q.empty()){
      int data = Q.front();
      Q.pop();
      printf(‚%dn‛, data);
  }
stack/queue 応用編
• キューの要素に構造体
  struct Human {
      int age;
      double height;
      char name[256];
  };
  int main()
  {
      queue<Human> Q;
      Human taro = {21, 168.5};
      strcpy(taro.name, ‚Taro Tanaka‛);
      Q.push(taro);
      printf(‚%dn‛, Q.front().age);
      return 0;
  }
stack/queue 応用編:幅優先探索
struct Data {
    int y, x, c;
};
int main() {
    int h, w, field[1000][1000], sy, sx, gy, gx, ans = -1;
    // 入力部省略
    bool visited[1000][1000] = {{false}};
    queue<Data> Q;
    Data start = {sy, sx, 0};
    Q.push(start);
    while(!Q.empty()){
        Data data = Q.front();
        Q.pop();
        if(data.y == gy && data.x == gx){
             ans = data.c;
             break;
        }
        if(visited[data.y][data.x]) continue;
        visited[data.y][data.x] = true;
        for(int i=0; i<4; ++i){
             int dy[] = {-1, 0, 0, 1}, dx[] = {0, 1, -1, 0};
             int py = data.y + dy[i], px = data.x + dx[i];
                    if(py<0 || h<=py || px<0 || w<=px || field[py][px]==1)
                 continue;
             Data next = {py, px, data.c+1};
             Q.push(next);
        }
    }
    printf(‚%dn‛, ans);
    return 0;
}
string

• 文字列クラス
  #include <string>
  using namespace std;


 – インクルードするフゔイル名は ‚string‛
 – ‚string.h‛ はC言語のヘッダ
 – ‚cstring‛ はC++での string.h


• C言語では char型の配列で表現
• C++では char型の配列やstring型で表現
文字列操作 ①入出力・基本操作

• C言語では
  char str[256];
  int length;

  /* 入力(空白・改行区切り) */
  scanf(‚%s‛, str);

  /* 長さ取得 */
  length = strlen(str);

  /* 先頭文字の変更 */
  str[0] = ‘a’;

  /* 出力 */
  printf(‚%s‛, str);
文字列操作 ①入出力・基本操作

• C++では
  string str;

  // 入力(空白・改行区切り)
  char tmp[256];
  scanf(‚%s‛, tmp); // 直接stringにscanf出来ない
  str = tmp;

  // 長さ取得
  int length = str.size();

  // 先頭文字の変更
  str[0] = ‘a’;

  // 出力
  printf(‚%s‛, str.c_str());
文字列操作 ②コピー・連結

• C言語では
  char str1[256], str2[256], str3[256];

  /* str2を ‛abcde‛ で初期化 */
  strcpy(str2, ‚abcde‛);

  /* str1にstr2をコピー */
  strcpy(str1, str2);

  /* str1の末尾にstr2を連結 */
  strcat(str1, str2);

  /* str1の末尾にstr2を連結したものをstr3に代入 */
  strcpy(str3, str1);
  strcat(str3, str2);
文字列操作 ②コピー・連結

• C++では
  string str1, str2, str3;

  /* str2を ‛abcde‛ で初期化 */
  str2 = ‚abcde‛;

  /* str1にstr2をコピー */
  str1 = str2;

  /* str1の末尾にstr2を連結 */
  str1 += str2;

  /* str1の末尾にstr2を連結したものをstr3に代入 */
  str3 = str1 + str2;
文字列操作 ③辞書順比較

• C言語では
  char str1[256], str2[256];
  int res;
  /* 入力省略 */
  /* str1とstr2について、以下のように場合分けする
   * ・A: str1がstr2よりも辞書順で早い場合
   * ・B: str1とstr2が等しい場合
   * ・C: str1がstr2よりも辞書順で遅い場合
   */
  res = strcmp(str1, str2);
  if(res < 0){
      /* (A) */
  }else if(res == 0){
      /* (B) */
  }else{
      /* (C) */
  }
文字列操作 ③辞書順比較

• C++では
  string str1, str2;

  // 入力省略
  /*
   * str1とstr2について、以下のように場合分けする
   * ・A: str1がstr2よりも辞書順で早い場合
   * ・B: str1とstr2が等しい場合
   * ・C: str1がstr2よりも辞書順で遅い場合
   */
  if(str1 < str2){
      // (A)
  }else if(str1 == str2){
      // (B)
  }else{
      // (C)
  }
文字列操作 ④部分文字列の抽出

• C言語では
  char str1[256], str2[256], str3[256];
  strcpy(str1, ‚abcde‛);

  /* str2 にstr1の3文字目から最後までの部分文字列を代入 */
  strcpy(str2, str1+2); /* str2 = ‚cde‛ */

  /* str3 にstr1の2文字目から3文字分の部分文字列を代入 */
  strncpy(str3, str1+1, 3);
  str3[3] = ‘0’;       /* str3 = ‚bcd‛ */
文字列操作 ④部分文字列の抽出

• C++では
  string str1, str2, str3;
  str1 = ‚abcde‛;

  // str2 にstr1の3文字目から最後までの部分文字列を代入
  str2 = str1.substr(2); // str2 = ‚cde‛

  // str3 にstr1の2文字目から3文字分の部分文字列を代入
  str3 = str1.substr(1, 3); // str3 = ‚bcd‛
文字列操作 ⑤応用編

• 文字列の配列をソート
  string str[100];
  for(int i=0; i<n; ++i){
      char tmp[256];
      scanf(‚%s‛, tmp);
      str[i] = tmp;
  }
  sort(str, str+n);

  /*
   * Sample Input
   * abcde eifj zzz abc def eifa
   *
   * Sample Output
   * abc abcde def eifa eifj zzz
   */
More Effective STL
• STLにはもっと色々な強力なデータ構造がある
 –   vector
 –   list
 –   deque
 –   set / multiset
 –   map / multimap
 –   priority_queue
 –   bitset
今日のまとめ
• CとC++の違い
  – stdio.h → cstdio
  – using namespace std; を忘れない


• C++新機能
  – フラグに使えるbool型
  – どこでも変数宣言可能


• STL
  – algorithm
  – stack / queue
  – string
練習問題
• stack
   – AOJ 0013
      • Switching Railroad Cars
      • PCK2003 本選16問目

• queue
   – AOJ 0558
      • Cheese
      • JOI10-11 予選5問目

   – AOJ 0193
      • Deven-Eleven
      • PCK2008 本選11問目



• queueとstring (とmap)
   – AOJ 0179
      • Mysterious Worm
      • PCK2008 予選7問目
1 de 63

Recomendados

組み込みでこそC++を使う10の理由 por
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
27K vistas32 diapositivas
勉強か?趣味か?人生か?―プログラミングコンテストとは por
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとはTakuya Akiba
71.8K vistas69 diapositivas
プログラムを高速化する話 por
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話京大 マイコンクラブ
242.4K vistas120 diapositivas
ゲーム開発者のための C++11/C++14 por
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
103.6K vistas157 diapositivas
競技プログラミングにおけるコードの書き方とその利便性 por
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
18.2K vistas29 diapositivas
Re永続データ構造が分からない人のためのスライド por
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
13K vistas88 diapositivas

Más contenido relacionado

La actualidad más candente

明日使えないすごいビット演算 por
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算京大 マイコンクラブ
63.4K vistas60 diapositivas
ウェーブレット木の世界 por
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
55.5K vistas67 diapositivas
色々なダイクストラ高速化 por
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化yosupo
25K vistas35 diapositivas
双対性 por
双対性双対性
双対性Yoichi Iwata
25.8K vistas89 diapositivas
プログラミングコンテストでの動的計画法 por
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法Takuya Akiba
91.7K vistas59 diapositivas

La actualidad más candente(20)

色々なダイクストラ高速化 por yosupo
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化
yosupo25K vistas
プログラミングコンテストでの動的計画法 por Takuya Akiba
プログラミングコンテストでの動的計画法プログラミングコンテストでの動的計画法
プログラミングコンテストでの動的計画法
Takuya Akiba91.7K vistas
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013 por Ryo Sakamoto
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
Ryo Sakamoto8.8K vistas
指数時間アルゴリズム入門 por Yoichi Iwata
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
Yoichi Iwata44.8K vistas
プログラミングコンテストでのデータ構造 por Takuya Akiba
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
Takuya Akiba104.9K vistas
プログラミングコンテストでの乱択アルゴリズム por Takuya Akiba
プログラミングコンテストでの乱択アルゴリズムプログラミングコンテストでの乱択アルゴリズム
プログラミングコンテストでの乱択アルゴリズム
Takuya Akiba26.8K vistas
中3女子でもわかる constexpr por Genya Murakami
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami49K vistas
組み込み関数(intrinsic)によるSIMD入門 por Norishige Fukushima
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima47.6K vistas
闇魔術を触ってみた por Satoshi Sato
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
Satoshi Sato6.7K vistas
充足可能性問題のいろいろ por Hiroshi Yamashita
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろ
Hiroshi Yamashita7.3K vistas
ARM CPUにおけるSIMDを用いた高速計算入門 por Fixstars Corporation
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
Fixstars Corporation7.1K vistas
数学プログラムを Haskell で書くべき 6 の理由 por Hiromi Ishii
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
Hiromi Ishii32.8K vistas
F#入門 ~関数プログラミングとは何か~ por Nobuhisa Koizumi
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi3.6K vistas
Rolling Hashを殺す話 por Nagisa Eto
Rolling Hashを殺す話Rolling Hashを殺す話
Rolling Hashを殺す話
Nagisa Eto4.1K vistas
Chokudai search por AtCoder Inc.
Chokudai searchChokudai search
Chokudai search
AtCoder Inc.14.1K vistas
オブジェクト指向できていますか? por Moriharu Ohzu
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu237.5K vistas

Similar a 競技プログラミングのためのC++入門

NumPyが物足りない人へのCython入門 por
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門Shiqiao Du
36.9K vistas71 diapositivas
C++コミュニティーの中心でC++をDISる por
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
12.4K vistas66 diapositivas
わんくま同盟大阪勉強会#61 por
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61TATSUYA HAYAMIZU
957 vistas66 diapositivas
C++0x総復習 por
C++0x総復習C++0x総復習
C++0x総復習道化師 堂華
4.9K vistas170 diapositivas
Cython intro prelerease por
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
1.8K vistas23 diapositivas
Pfi Seminar 2010 1 7 por
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Preferred Networks
3.4K vistas60 diapositivas

Similar a 競技プログラミングのためのC++入門(20)

NumPyが物足りない人へのCython入門 por Shiqiao Du
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Shiqiao Du36.9K vistas
C++コミュニティーの中心でC++をDISる por Hideyuki Tanaka
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
Hideyuki Tanaka12.4K vistas
わんくま同盟大阪勉強会#61 por TATSUYA HAYAMIZU
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU957 vistas
Cython intro prelerease por Shiqiao Du
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
Shiqiao Du1.8K vistas
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30) por Hiro H.
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
Hiro H.4K vistas
C++0x in programming competition por yak1ex
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex1.8K vistas
.NET Core 2.x 時代の C# por 信之 岩永
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
信之 岩永6.2K vistas
Brief introduction of Boost.ICL por yak1ex
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
yak1ex692 vistas
T69 c++cli ネイティブライブラリラッピング入門 por 伸男 伊藤
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤5.2K vistas
Python standard 2022 Spring por anyakichi
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi218 vistas
C++11概要 ライブラリ編 por egtra
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra3K vistas
C++0x in programming competition por yak1ex
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex1K vistas
新しい並列for構文のご提案 por yohhoy
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
yohhoy29.6K vistas
Clojure programming-chapter-2 por Masao Kato
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato1.1K vistas

Último

定例会スライド_キャチs 公開用.pdf por
定例会スライド_キャチs 公開用.pdf定例会スライド_キャチs 公開用.pdf
定例会スライド_キャチs 公開用.pdfKeio Robotics Association
146 vistas64 diapositivas
Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向 por
Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向
Keycloakの全体像: 基本概念、ユースケース、そして最新の開発動向Hitachi, Ltd. OSS Solution Center.
109 vistas26 diapositivas
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」 por
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」PC Cluster Consortium
66 vistas12 diapositivas
光コラボは契約してはいけない por
光コラボは契約してはいけない光コラボは契約してはいけない
光コラボは契約してはいけないTakuya Matsunaga
28 vistas17 diapositivas
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」 por
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」PC Cluster Consortium
28 vistas36 diapositivas

Último(7)

PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」 por PC Cluster Consortium
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」
光コラボは契約してはいけない por Takuya Matsunaga
光コラボは契約してはいけない光コラボは契約してはいけない
光コラボは契約してはいけない
Takuya Matsunaga28 vistas
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」 por PC Cluster Consortium
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」

競技プログラミングのためのC++入門

  • 1. 競技プログラミングのための C++入門 @natrium11321
  • 2. C++ って何? • C言語の進化系(の一つ) C++ • オブジェクト指向 C言語 • 参照型 • 例外機構 • 配列 • 演算子オーバーロード • 関数 • 実行時型情報 • ポインタ • テンプレート • STL • 構造体 • スレッド (C++11より) • 型推論 • ラムダ式
  • 3. C++ って何? • C言語の進化系(の一つ) C++ 使えると • オブジェクト指向 C言語 • 参照型 競技でめっちゃ • 例外機構 • 配列 便利!!! • 演算子オーバーロード • 関数 • 実行時型情報 • ポインタ • テンプレート • STL • 構造体 • スレッド (C++11より) • 型推論 • ラムダ式
  • 4. C++ことはじめ C++を入門します
  • 5. C++ことはじめ • C言語の Hello, world! hello.c #include <stdio.h> int main(void) { printf(‚Hello, world!n‛); return 0; }
  • 6. C++ことはじめ • C++の Hello, world! hello.cpp #include <cstdio> using namespace std; int main() { printf(‚Hello, world!n‛); return 0; } 本当はC言語版のコードもそのまま動くが…
  • 7. CとC++の違い hello.c #include <stdio.h> int main(void) { printf(‚Hello, world!n‛); return 0; } !? hello.cpp #include <cstdio> using namespace std; int main() { printf(‚Hello, world!n‛); return 0; }
  • 8. CとC++の違い ①拡張子 • C言語では • C++では – test.c – test.cpp – hoge.c – hoge.cpp
  • 9. CとC++の違い hello.c #include <stdio.h> int main(void) { printf(‚Hello, world!n‛); return 0; } !?!? hello.cpp #include <cstdio> using namespace std; int main() { printf(‚Hello, world!n‛); return 0; }
  • 10. CとC++の違い ②ヘッダ名 • C言語では • C++では – stdio.h – cstdio – stdlib.h – cstdlib – math.h – cmath – string.h – cstring – ctype.h – cctype cstdio:「C言語の時からあるstdioという名前のヘッダ」 ↓ C++で新たに追加されたヘッダには ’c’ は付かない
  • 11. CとC++の違い hello.c #include <stdio.h> int main(void) { printf(‚Hello, world!n‛); return 0; } hello.cpp #include <cstdio> using namespace std; ☆おまじない☆ !?!??! int main() { printf(‚Hello, world!n‛); return 0; }
  • 12. CとC++の違い hello.c #include <stdio.h> int main(void) { printf(‚Hello, world!n‛); return 0; } hello.cpp #include <cstdio> using namespace std; !?!??!!? int main() { printf(‚Hello, world!n‛); return 0; }
  • 13. CとC++の違い ③引数のvoid void.c void.cpp #include <stdio.h> #include <cstdio> using namespace std; void func(void); void func(); int main(void) int main() { { func(); func(); return 0; return 0; } } void func(void) void func() { { printf(‚fugafugan‛); printf(‚fugafugan‛); } } • C++では引数のvoidを省略可 – 引数のみ
  • 15. CとC++の違い ④構造体 • C言語の構造体 structure.c struct Human { int age; double weight; char name[256]; }; int main(void) { struct Human taro; taro.age = 21; … }
  • 16. CとC++の違い ④構造体 • C言語の構造体 (typedef) structure.c typedef struct { int age; double weight; char name[256]; } Human; int main(void) { Human taro; taro.age = 21; … }
  • 17. CとC++の違い ④構造体 • C++の構造体 structure.cpp struct Human { int age; double weight; char name[256]; }; int main() { Human taro; taro.age = 21; … }
  • 18. C++新機能紹介 boolと変数の宣言位置
  • 19. C++新機能 ①bool eratos.c /* * n以下のxについて isprime[x] == 1 だったらxは素数 * という配列isprimeを作る */ void make_sieve(int n, int isprime[]) { int i, j; isprime[0] = isprime[1] = 0; for(i=2; i<=n; ++i) isprime[i] = 1; for(i=2; i<=n; ++i){ if(isprime[i] == 1){ for(j=i*2; j<=n; j+=i) isprime[j] = 0; } } }
  • 20. C++新機能 ①bool 2,147,483,647まで格納できるintに ( ^o^) 0か1しか格納しないのは勿体無いな… 待てよ、書いてたコード ( ˘⊖˘) C++だっけ… ( ◠‿◠ )☛ そこに気づいてしまったか… 貴様にはbool型を使ってもらおう ▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂ うわあああああああ
  • 21. C++新機能 ①bool • bool型変数(1bit整数) bool flag; • 値は true(真) か false(偽) を代入 flag = true; // 数値としては1 flag = false; // 数値としては0 • if で使う if(flag){ puts(‚flag is true‛); } else{ puts(‚flag is false‛); }
  • 22. C++新機能 ①bool • 比較の結果を格納 int a = 3, b = 5; flag = a < b; // true flag = a != b; // true flag = a >= b; // false • 否定演算 bool flag1 = true; bool flag2 = !flag1; // false bool flag3 = !flag2; // true if(!flag){ puts(‚flag is false‛); } else{ puts(‚flag is true‛); }
  • 23. C++新機能 ①bool eratos.cpp // n以下のxについて isprime[x] がtrueだったらxは素数 // という配列isprimeを作る void make_sieve(int n, bool isprime[]) { int i, j; isprime[0] = isprime[1] = false; for(i=2; i<=n; ++i) isprime[i] = true; for(i=2; i<=n; ++i){ if(isprime[i]){ for(j=i*2; j<=n; j+=i) isprime[j] = false; } } }
  • 24. C++新機能 ①bool • bool を使うメリット  int flag; bool flag; 「これはフラグを表す変数です」 というのが分かりやすい  flag = 1; flag = true;  0や1といった怪しい数字で 場合分けしなくて良い  int : 4バイト bool : 1バイト  メモリを節約できる
  • 25. C++新機能 ②変数の宣言位置 gucha.c /* プログラム速いけど微妙にバグる */ int main(void) { int i, j, k, n, a[1024]; int map[1024][1024]; int from, to, end, *p, *q; char c, s, t, str[128]; … } \(^o^)/ どの変数をどこで使ってるかが分からん!
  • 26. C++新機能 ②変数の宣言位置 smart.cpp ここだけ int main() { int n; じゃなく scanf(‚%d‛, &n); int a[1024]; ここでも for(int i=0; i<n; ++i) scanf(‚%d‛, &a[i]); int map[1024][1024]; ここでも for(int i=0; i<n; ++i){ for(int j=0; j<n; ++j){ map[i][j] = 0; ここでも for(int k=0; k<n; ++k) map[i][j] += a[i] * a[(j+k)%n]; } } … この辺でも }
  • 27. C++新機能 ②変数の宣言位置 • どこでも変数宣言が出来る – 特にforの中でのループ変数の宣言は便利 • どこでも変数宣言が出来るメリット  変数を使う直前に宣言できる どこで変数を使ってるかが分かりやすい! 宣言部分がごちゃごちゃしない! 初期化を忘れない!
  • 28. C++新機能 ②変数の宣言位置 eratos_smart.cpp // n以下のxについて isprime[x] がtrueだったらxは素数 // という配列isprimeを作る void make_sieve(int n, bool isprime[]) { isprime[0] = isprime[1] = false; for(int i=2; i<=n; ++i) isprime[i] = true; for(int i=2; i<=n; ++i){ if(isprime[i]){ for(int j=i*2; j<=n; j+=i) isprime[j] = false; } } }
  • 29. STL (Standard Template Library) algorithm, stack, queue, string
  • 30. STLって何? • C++の標準ライブラリ(の一部) • とても便利な機能が沢山詰まってます – 特に競技プログラミングでは重宝 • 本日紹介するのは – <algorithm> – <stack> – <queue> – <string>
  • 31. algorithm • 便利な関数の詰め合わせセット #include <algorithm> using namespace std; • 基本的にSTLの関数は引数の型について不問 – 「テンプレート」で実現 – 今日は詳しくやりません
  • 32. 最大値・最小値 • min(a, b) – aとbの小さい方の値を返す • max(a, b) – aとbの大きい方の値を返す int a = 10, b = 4; int small = min(a, b); // 4 int large = max(a, b); // 10 double c = 1.2, d = 5.8; double e = max(c*c, d*d); // int 以外もOK double f = min(a, c); // 違う型を渡すとエラー double g = min((double)a, c); // キャストすればOK
  • 33. 交換 • swap(a, b) – aとb の値を交換する int a = 10, b = 4; printf(‚a is %d, b is %dn‛, a, b); // a is 10, b is 4 swap(a, b); printf(‚a is %d, b is %dn‛, a, b); // a is 4, b is 10 int* p = &a; int* q = &b; swap(p, q); *q += 3; printf(‚a is %d, b is %dn‛, a, b); // a is 7, b is 10
  • 34. ソーティング • sort(f, t) – f から t-1 までを昇順にソートする – f と t は配列のポインタ – 時間計算量 O(nlogn) int a[] = {5, 3, 7, 8, 2}; sort(a, a+5); for(int i=0; i<5; ++i) printf(‚%d ‚, a[i]); /* * 出力結果 * 2 3 5 7 8 */
  • 35. ソーティング • reverse(f, t) – f から t-1 までを反転させる – 降順にソートしたければこれを使う – 時間計算量 O(n) int a[] = {5, 3, 7, 8, 2}; reverse(a, a+5); // a = {2, 8, 7, 3, 5} sort(a, a+5); // a = {2, 3, 5, 7, 8} reverse(a, a+5); // a = {8, 7, 5, 3, 2}
  • 36. 数え上げ • count(f, t, x) – f から t-1 までに含まれるxの数を返す int a[] = {1, 4, 8, 2, 8, 6, 8, 1}; int cnt8 = count(a, a+8, 8); // 3 int cnt4 = count(a, a+8, 4); // 1 – この関数のせいで ‚count‛ という名前の変数を作 るとエラーが起こる • ‚cnt‛ とかで代用
  • 37. 初期化 • fill(f, t, x) – f から t-1 までを全て x で初期化する int a[] = {1, 4, 8, 2, 8, 6, 8, 1}; fill(a, a+8, 1); // a = {1, 1, 1, 1, 1, 1, 1, 1} fill(a+2, a+5, 8); // a = {1, 1, 8, 8, 8, 1, 1, 1} bool flags[1000]; fill(flags, flags+1000, true);
  • 38. algorithm • ほかにも便利な関数いろいろ – equal, find, search, copy, remove, replace, random_shuffle, unique, lower_bound, upper_ bound, binary_search, max_element, min_elem ent, next_permutation, etc… これらを知らないと猛烈に不利ということはない! (ループ回せば普通にできる、JOI予選程度では使わない、等)
  • 39. stack/queue • スタックとキュー 8 8 3 3 stack queue (先入れ後出し) (先入れ先出し)
  • 40. stack/queue • スタックとキュー #include <stack> #include <queue> using namespace std;
  • 42. クラスって何? • C言語の構造体に毛が生えたもの • 変数だけではなく、関数も中に入れられる – C++では構造体の中にも関数作れるけどね • クラスの中の変数:メンバ変数 • クラスの中の関数:メンバ関数 • 使うだけなら簡単です
  • 43. stack • スタックの宣言 stack<int> S; stack<int> というクラス(型)の、 Sという名前の変数 を作成(インスタンス) int はスタックに格納する 変数の型を表す
  • 44. stack • スタックへの追加 stack<int> S; S.push(3); S.push(x) S.push(5); Sにxを追加 S.push(-2); -2 5 3
  • 45. stack • スタックの先頭要素の取り出し stack<int> S; S.push(3); S.top() S.push(5); 現在のSの先頭要素を返す S.push(-2); (削除はしない) printf(‚%dn‛, S.top()); S.pop(); printf(‚%dn‛, S.top()); S.pop() S.pop(); 現在のSの先頭要素を削除 S.push(20); 20 3
  • 46. stack • スタックのサイズ確認 stack<int> S; S.push(3); S.push(5); S.size() S.push(-2); Sに含まれる要素数を返す int cnt = S.size(); bool isempty = S.empty(); S.empty() Sが空かどうかを返す // スタックの全ての要素を取り出して表示 while(!S.empty()){ int data = S.top(); S.pop(); printf(‚%dn‛, data); }
  • 47. queue • キューの宣言・追加・先頭要素の取り出し queue<int> Q; Q.push(3); Q.push(x) Q.push(5); Qにxを追加 Q.push(-2); printf(‚%dn‛, Q.front()); Q.pop(); Q.front() printf(‚%dn‛, Q.front()); 現在のQの先頭要素を返す Q.pop(); (削除はしない) Q.push(20); Q.pop() 現在のQの先頭要素を削除 20 -2
  • 48. queue • キューのサイズ確認 queue<int> Q; Q.push(3); Q.push(5); Q.size() Q.push(-2); Qに含まれる要素数を返す int cnt = Q.size(); bool isempty = Q.empty(); Q.empty() Qが空かどうかを返す // キューの全ての要素を取り出して表示 while(!Q.empty()){ int data = Q.front(); Q.pop(); printf(‚%dn‛, data); }
  • 49. stack/queue 応用編 • キューの要素に構造体 struct Human { int age; double height; char name[256]; }; int main() { queue<Human> Q; Human taro = {21, 168.5}; strcpy(taro.name, ‚Taro Tanaka‛); Q.push(taro); printf(‚%dn‛, Q.front().age); return 0; }
  • 50. stack/queue 応用編:幅優先探索 struct Data { int y, x, c; }; int main() { int h, w, field[1000][1000], sy, sx, gy, gx, ans = -1; // 入力部省略 bool visited[1000][1000] = {{false}}; queue<Data> Q; Data start = {sy, sx, 0}; Q.push(start); while(!Q.empty()){ Data data = Q.front(); Q.pop(); if(data.y == gy && data.x == gx){ ans = data.c; break; } if(visited[data.y][data.x]) continue; visited[data.y][data.x] = true; for(int i=0; i<4; ++i){ int dy[] = {-1, 0, 0, 1}, dx[] = {0, 1, -1, 0}; int py = data.y + dy[i], px = data.x + dx[i]; if(py<0 || h<=py || px<0 || w<=px || field[py][px]==1) continue; Data next = {py, px, data.c+1}; Q.push(next); } } printf(‚%dn‛, ans); return 0; }
  • 51. string • 文字列クラス #include <string> using namespace std; – インクルードするフゔイル名は ‚string‛ – ‚string.h‛ はC言語のヘッダ – ‚cstring‛ はC++での string.h • C言語では char型の配列で表現 • C++では char型の配列やstring型で表現
  • 52. 文字列操作 ①入出力・基本操作 • C言語では char str[256]; int length; /* 入力(空白・改行区切り) */ scanf(‚%s‛, str); /* 長さ取得 */ length = strlen(str); /* 先頭文字の変更 */ str[0] = ‘a’; /* 出力 */ printf(‚%s‛, str);
  • 53. 文字列操作 ①入出力・基本操作 • C++では string str; // 入力(空白・改行区切り) char tmp[256]; scanf(‚%s‛, tmp); // 直接stringにscanf出来ない str = tmp; // 長さ取得 int length = str.size(); // 先頭文字の変更 str[0] = ‘a’; // 出力 printf(‚%s‛, str.c_str());
  • 54. 文字列操作 ②コピー・連結 • C言語では char str1[256], str2[256], str3[256]; /* str2を ‛abcde‛ で初期化 */ strcpy(str2, ‚abcde‛); /* str1にstr2をコピー */ strcpy(str1, str2); /* str1の末尾にstr2を連結 */ strcat(str1, str2); /* str1の末尾にstr2を連結したものをstr3に代入 */ strcpy(str3, str1); strcat(str3, str2);
  • 55. 文字列操作 ②コピー・連結 • C++では string str1, str2, str3; /* str2を ‛abcde‛ で初期化 */ str2 = ‚abcde‛; /* str1にstr2をコピー */ str1 = str2; /* str1の末尾にstr2を連結 */ str1 += str2; /* str1の末尾にstr2を連結したものをstr3に代入 */ str3 = str1 + str2;
  • 56. 文字列操作 ③辞書順比較 • C言語では char str1[256], str2[256]; int res; /* 入力省略 */ /* str1とstr2について、以下のように場合分けする * ・A: str1がstr2よりも辞書順で早い場合 * ・B: str1とstr2が等しい場合 * ・C: str1がstr2よりも辞書順で遅い場合 */ res = strcmp(str1, str2); if(res < 0){ /* (A) */ }else if(res == 0){ /* (B) */ }else{ /* (C) */ }
  • 57. 文字列操作 ③辞書順比較 • C++では string str1, str2; // 入力省略 /* * str1とstr2について、以下のように場合分けする * ・A: str1がstr2よりも辞書順で早い場合 * ・B: str1とstr2が等しい場合 * ・C: str1がstr2よりも辞書順で遅い場合 */ if(str1 < str2){ // (A) }else if(str1 == str2){ // (B) }else{ // (C) }
  • 58. 文字列操作 ④部分文字列の抽出 • C言語では char str1[256], str2[256], str3[256]; strcpy(str1, ‚abcde‛); /* str2 にstr1の3文字目から最後までの部分文字列を代入 */ strcpy(str2, str1+2); /* str2 = ‚cde‛ */ /* str3 にstr1の2文字目から3文字分の部分文字列を代入 */ strncpy(str3, str1+1, 3); str3[3] = ‘0’; /* str3 = ‚bcd‛ */
  • 59. 文字列操作 ④部分文字列の抽出 • C++では string str1, str2, str3; str1 = ‚abcde‛; // str2 にstr1の3文字目から最後までの部分文字列を代入 str2 = str1.substr(2); // str2 = ‚cde‛ // str3 にstr1の2文字目から3文字分の部分文字列を代入 str3 = str1.substr(1, 3); // str3 = ‚bcd‛
  • 60. 文字列操作 ⑤応用編 • 文字列の配列をソート string str[100]; for(int i=0; i<n; ++i){ char tmp[256]; scanf(‚%s‛, tmp); str[i] = tmp; } sort(str, str+n); /* * Sample Input * abcde eifj zzz abc def eifa * * Sample Output * abc abcde def eifa eifj zzz */
  • 61. More Effective STL • STLにはもっと色々な強力なデータ構造がある – vector – list – deque – set / multiset – map / multimap – priority_queue – bitset
  • 62. 今日のまとめ • CとC++の違い – stdio.h → cstdio – using namespace std; を忘れない • C++新機能 – フラグに使えるbool型 – どこでも変数宣言可能 • STL – algorithm – stack / queue – string
  • 63. 練習問題 • stack – AOJ 0013 • Switching Railroad Cars • PCK2003 本選16問目 • queue – AOJ 0558 • Cheese • JOI10-11 予選5問目 – AOJ 0193 • Deven-Eleven • PCK2008 本選11問目 • queueとstring (とmap) – AOJ 0179 • Mysterious Worm • PCK2008 予選7問目