27
Copyright 2008 Hiro Yoshioka All rights reserved 1 セキュリティ&プログラミングキャンプ 2008 プログラミング入門2 アルゴリズムとデータ構造 ミラクル・リナックス株式会社 よしおかひろたか

programming camp 2008, introduction of programming, algorithm

Embed Size (px)

DESCRIPTION

プログラミング入門、アルゴリズム

Citation preview

Page 1: programming camp 2008, introduction of programming, algorithm

Copyright 2008 Hiro Yoshioka All r ights reserved 1

セキュリティ&プログラミングキャンプ2008

プログラミング入門2アルゴリズムとデータ構造

ミラクル・リナックス株式会社よしおかひろたか

Page 2: programming camp 2008, introduction of programming, algorithm

Contents

• はじめに• アルゴリズムとは

Page 3: programming camp 2008, introduction of programming, algorithm

はじめに• アルゴリズムとは

– 問題を解くための手順を定式化して表現したもの

– コンピュータにアルゴリズムを指示するための命令をプログラムという

Page 4: programming camp 2008, introduction of programming, algorithm

アルゴリズムの例

• ユークリッドの互除法二つの自然数の最大公約数を求める– 入力をm,n (m ≧ n)– n =0 なら、 m を出力して終了– n が m を割り切るなら、 n を出力して終了– m を n で割った余りを新たに m とし、更に m と n

を取り替えて、一つ前に戻る。

Page 5: programming camp 2008, introduction of programming, algorithm

プログラムの例#include<stdio.h>int main(void){    int m, n, tmp;

    scanf("%d %d", &m, &n);    if(m < 0 || n < 0){        puts("Error");        return 1;    }    while(n){        tmp = m % n;        m = n;        n = tmp;    }    printf("%d\n", m);    return 0;}

Page 6: programming camp 2008, introduction of programming, algorithm

なぜアルゴリズムを学ぶのか

• 優れた先達の知恵がある– 優れたアルゴリズムはシンプルで美しい

• 優れたアルゴリズムとは何かを学ぶため– 優れたアルゴリズムもそうでないアルゴリズムもあ

る??– アルゴリズムの解析

Page 7: programming camp 2008, introduction of programming, algorithm

アルゴリズムとデータ構造

• 優れたアルゴリズムやデータ構造を利用すれば、問題をあっという間に解けてしまう場合がある。– どんなことが解明されているかを調べてみなけれ

ばならない。– さもないと、優れた手法が存在するのに、自己流

の下手なやり方を考案するのに時間を無駄にする。

– 自己流のアルゴリズムは• 開発に時間がかかって• 実行時間も遅くて• バグも多く、拡張性も低い

Page 8: programming camp 2008, introduction of programming, algorithm

アルゴリズムとデータ構造

• アルゴリズムとデータ構造をまったく新たに考案しなければならないということはめったにない。

• 基本的なアルゴリズムとデータ構造の組み合わせで、多くの問題は解ける。

Page 9: programming camp 2008, introduction of programming, algorithm

基本的なアルゴリズムとデータ構造

• 検索• ソーティング(並べ替え)• O記法• リスト• ツリー• ハッシュテーブル

参考文献:プログラミング作法、Kernighan & Pike

Page 10: programming camp 2008, introduction of programming, algorithm

検索

• 配列:静的な表形式のデータを格納する• 逐次検索:個々の要素を順番に調べていって

希望の要素かどうか調べる

/* lookup: 配列中の単語を逐次検索する */int lookup(char *word, char *array[]){    int i;    for (i = 0; array[i] != NULL; i++)        if (strcmp(word, array[i]) == 0)            return i;    return ­1;}

Page 11: programming camp 2008, introduction of programming, algorithm

検索

• 逐次検索:特徴– データ量が少ないときには十分高速– 実装例:strchr, strstr– 作業量(実行時間):データ量に比例

• データ量が倍になれば検索時間も倍

Page 12: programming camp 2008, introduction of programming, algorithm

検索

• 二分検索– 表のデータがソート(小さい順に並んでいる)され

ていると仮定する。– まず真ん中の要素を調べて、その値が自分が探し

ている値より大きかったら前半を調べ、小さければ後半を調べる。

–辞書を引くようなもの。justはquiteより前にあって、actuallyより後ろにある。

actually, ... , just, ... , quite, ... , really, ... , zeta

Page 13: programming camp 2008, introduction of programming, algorithm

二分検索

int binary_lookup(char *name, char *array[], int ntab){    int low, high, mid, cmp;    low = 0;    high = ntab ­ 1;    while (low <= high) {      mid = (low + high) / 2;      cmp = strcmp(name, array[mid]);      if (cmp < 0)

  high = mid ­1;      else if (cmp > 0)

  low = mid + 1;      else

  return mid;    }    return ­1;}

Page 14: programming camp 2008, introduction of programming, algorithm

検索

• 二分検索– 作業量:データ量のlog2(n)に比例

• 作業量の比較– 1000個のデータの比較

• 逐次検索:最大1000回• 二分検索:最大約10回

– 100万個のデータの比較• 逐次検索:最大100万回• 二分検索:最大約20回

Page 15: programming camp 2008, introduction of programming, algorithm

ソーティング

• ソーティング:レコードの集まりをキーの値の大小関係によって並べ替えること。

• アルゴリズムの例– 配列の要素を1個選択する(ピボット)– その他の要素を2つのグループに分割する

• ピボット値より小さい「チビ」• ピボット値より大きいか等しい「デカ」

– 個々のグループを上記のアルゴリズムでソートする

Page 16: programming camp 2008, introduction of programming, algorithm

ソーティングvoid quicksort(int v[], int n){    int i, last;    if (n <= 1)        return;    swap(v, 0, rand() % n);    last = 0;    for (i = 1; i < n; i++)        if (v[i] < v[0])            swap(v, ++last, i);    swap(v, 0, last);    quicksort(v, last);    quicksort(v+last+1, n­last­1);}

void swap(int v[], int i, int j){    int temp;    temp = v[i];    v[i] = v[j];    v[j] = temp;}

Page 17: programming camp 2008, introduction of programming, algorithm

O記法

• O記法:計算量(実行時間)を入力のサイズnの関数で表現する。

• 例:入力に含まれる要素数nによって、特定のアルゴリズムによって処理される作業量を表す。例えば、逐次検索の作業量はnに比例するし、二分検索の作業量はlog2(n)に比例する。この時、逐次検索はO(n)のアルゴリズムであると言う。二分検索はO(log2(n))のアルゴリズムである。

Page 18: programming camp 2008, introduction of programming, algorithm

O記法

• 記法 名称 アルゴリズム例• O(1) 定数 配列インデックス• O(log(n)) 対数 二分検索• O(n) 1次 文字列比較• O(nlog(n)) nlog(n) クイックソート• O(n²) 2次 単純なソート• O(n³) 3次 行列乗算

• O(2n) 指数 集合分割問題

Page 19: programming camp 2008, introduction of programming, algorithm

リスト

ヘッド

データ データ データ データ データ

NULL

ポインタ

• 単一リンクリスト:データと次の項目へのポインタを含んでいる項目の集合

• サイズ:– 配列:固定長– リスト:可変長

Page 20: programming camp 2008, introduction of programming, algorithm

配列とリスト

ヘッド

データ データ データ データ データ

NULL

ポインタ

• 順序の変更– 配列:ブロック移動– リスト:ポインタのつけかえ

• 項目の追加(サイズの変更)– 配列:通常は静的なサイズなのでできない– リスト:項目の追加、削除は容易

Page 21: programming camp 2008, introduction of programming, algorithm

リスト

name: データ

next: NULL

typedef struct Name Name;struct Name {    Name *next;    char *name;};

Name *newitem(char *name){    Name *newp;

    newp = (Name *) malloc(sizeof(Name));    if (newp == NULL)        exit(2);    newp­>next = NULL;    newp­>name = name;    return newp;}

Page 22: programming camp 2008, introduction of programming, algorithm

リスト:先頭に追加

Name *addfront(Name *listp, Name *newp){    newp­>next = listp;    return newp;}/* 使用例 */nvlist = addfront(nvlist, newitem("smiley"));

name:”smiley”

next: NULL

nvlist

name:”smiley”

next: NULLnvlist

NULL

nvlist NULL

Page 23: programming camp 2008, introduction of programming, algorithm

リストの検索

Name *lookup(Name *listp, char *name){    for ( ; listp != NULL; listp = listp­>next)      if (strcmp(name, listp­>name) == 0)          return listp;    return NULL;}

Page 24: programming camp 2008, introduction of programming, algorithm

ツリー

• 二分木

Page 25: programming camp 2008, introduction of programming, algorithm

ハッシュテーブル

• 要素数Nの配列を用意し、キーの値を元に、0からN-1までの値を取る関数(ハッシュ関数)によってレコード(キーと値のペア)を格納する。

出典:Wikipedia:ハッシュテーブル

Page 26: programming camp 2008, introduction of programming, algorithm

まとめ

• 様々なアルゴリズムがある。• 使えそうなアルゴリズムとデータ構造を選択し

よう。• 配列、リスト、ツリー、ハッシュテーブルが基本だ。

Page 27: programming camp 2008, introduction of programming, algorithm

参考文献

• プログラミング作法、Braian W. Kernighan, Rob Pike, ISBN 4-7561-3649-4