SlideShare a Scribd company logo
1 of 63
競技プログラミングのための
    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問目

More Related Content

What's hot

Constexprとtemplateでコンパイル時にfizz buzz
Constexprとtemplateでコンパイル時にfizz buzzConstexprとtemplateでコンパイル時にfizz buzz
Constexprとtemplateでコンパイル時にfizz buzz
京大 マイコンクラブ
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
Satoshi Sato
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
Takuya Akiba
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 

What's hot (20)

競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
Constexprとtemplateでコンパイル時にfizz buzz
Constexprとtemplateでコンパイル時にfizz buzzConstexprとtemplateでコンパイル時にfizz buzz
Constexprとtemplateでコンパイル時にfizz buzz
 
最新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月)
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
C言語ポインタ講座 (Lecture of Pointer in C)
C言語ポインタ講座 (Lecture of Pointer in C)C言語ポインタ講座 (Lecture of Pointer in C)
C言語ポインタ講座 (Lecture of Pointer in C)
 
色々なダイクストラ高速化
色々なダイクストラ高速化色々なダイクストラ高速化
色々なダイクストラ高速化
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
すごい配列楽しく学ぼう
すごい配列楽しく学ぼうすごい配列楽しく学ぼう
すごい配列楽しく学ぼう
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
LLVM最適化のこつ
LLVM最適化のこつLLVM最適化のこつ
LLVM最適化のこつ
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 

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

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
digitalghost
 

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

NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0C# 9.0 / .NET 5.0
C# 9.0 / .NET 5.0
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
More C++11
More C++11More C++11
More C++11
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
boost - std - C#
boost - std - C#boost - std - C#
boost - std - C#
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 

Recently uploaded

Recently uploaded (11)

論文紹介: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...
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
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
 
論文紹介: 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
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 

競技プログラミングのための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問目