Top Banner
データ構造 with Haskell
93

Deque with Haskel

Feb 18, 2017

Download

Science

Ken Ogura
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Deque with Haskel

データ構造with Haskell

Page 2: Deque with Haskel

目次

● Stack● Queue● Deque

Page 3: Deque with Haskel

目次

● Stack● Queue● Deque

● 全部配列を使えば一瞬じゃないか!いいかげんにしろ!

Page 4: Deque with Haskel

残念ながら

配列なんて無いよ

Page 5: Deque with Haskel

Haskellのデータ構造

● 配列は一応あるよ

– ただし代入に O(N) かかる

Page 6: Deque with Haskel

Haskellのデータ構造

● リストというのを使います● 次の操作が可能

– 先頭に値を追加 O(1)– 先頭から削除 O(1)– n番目にアクセス O(n)

● 厳密にはちょっと違うけどだいたいあってる

Page 7: Deque with Haskel

Haskellのリスト

● [3, 1, 4, 1, 5] –-リストの例● 追加

– 9 : [3, 1, 4, 1, 5] → [9, 3, 1, 4, 1, 5]● 先頭を得る

– head [3, 1, 4, 1, 5] → 3● 先頭以外を得る

– tail [3, 1, 4, 1, 5] → [1, 4, 1, 5]– tail [1] → [ ] –- 空のリスト

Page 8: Deque with Haskel

Haskellのリスト

● 先頭にくっつける (:)● 先頭を参照する head● 先頭以外を参照する tail

● これらは以降たくさん出てくるのでよく覚えていてね

Page 9: Deque with Haskel

1つめのデータ構造

Stack

Page 10: Deque with Haskel

Stack

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の先頭から値を取り出す (pop)

Page 11: Deque with Haskel

Stack:図示

● 空のStackがあるじゃろ– 左側が先頭

Page 12: Deque with Haskel

Stack:図示

● push(4)

4

Page 13: Deque with Haskel

Stack:図示

● push(4), push(1)

41

Page 14: Deque with Haskel

Stack:図示

● push(4), push(1), push(1)

411

Page 15: Deque with Haskel

Stack:図示

● push(4), push(1), push(1), pop()

411

Page 16: Deque with Haskel

Stack:図示

● push(4), push(1), push(1), pop(), push(5)

4155

Page 17: Deque with Haskel

Stack

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の先頭から値を取り出す (pop)

Page 18: Deque with Haskel

Stack

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の先頭から値を取り出す (pop)

● すごい既視感

Page 19: Deque with Haskel

Haskellのデータ構造 (再掲)

● リストというのを使います● 次の操作が可能

– 先頭に値を追加 O(1)– 先頭から削除 O(1)– n番目にアクセス O(n)

● 厳密にはちょっと違うけどだいたいあってる

Page 20: Deque with Haskel

Haskellのデータ構造 (再掲)

● リストというのを使います● 次の操作が可能

– 先頭に値を追加 O(1)– 先頭から削除 O(1)– n番目にアクセス O(n)

● 厳密にはちょっと違うけどだいたいあってる

Page 21: Deque with Haskel

Stack

● スタック● リストをそのまま使える

– やったぜ

Page 22: Deque with Haskel

Stack: 実装

(ソースコードをここに書く)

(説明をここに書く)

Page 23: Deque with Haskel

Stack: 実装

Data Stack a = S [a]

Stack型の定義

Page 24: Deque with Haskel

Stack: 実装

Data Stack a = S [a]

push (S xs) x = S (x:xs)

pushの定義

Page 25: Deque with Haskel

Stack: 実装

Data Stack a = S [a]

push (S xs) x = S (x:xs)

pop (x:xs) = (x, S xs)

popの定義

Page 26: Deque with Haskel

Stack: 実装

Data Stack a = S [a]

push (S xs) x = S (x:xs)

pop (x:xs) = (x, S xs)

空のStackをpopしないことは良心にまかせる

Page 27: Deque with Haskel

Stack: 実装

Data Stack a = S [a]

push (S xs) x = S (x:xs)

pop (x:xs) = (x, S xs)

完成

Page 28: Deque with Haskel

1つめのデータ構造

Queue

Page 29: Deque with Haskel

Queue

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の末尾から値を取り出す (pop)

Page 30: Deque with Haskel

Queue: 図示

● 空のQueueがあるじゃろ

– 左側から入って、右側から出る

Page 31: Deque with Haskel

Queue: 図示

● push(3)

3

Page 32: Deque with Haskel

Queue: 図示

● push(3), push(7)

37

Page 33: Deque with Haskel

Queue: 図示

● push(3), push(7), push(2)

372

Page 34: Deque with Haskel

Queue: 図示

● push(3), push(7), push(2), pop()

372

Page 35: Deque with Haskel

Queue: 図示

● push(3), push(7), push(2), pop()

72

Page 36: Deque with Haskel

Queue: 図示

● push(3), push(7), push(2), pop(), push(9)

729

Page 37: Deque with Haskel

Queue: 図示

● push(3), push(7), push(2), pop(), push(9)pop()

729

Page 38: Deque with Haskel

Queue

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の末尾から値を取り出す (pop)

Page 39: Deque with Haskel

Queue

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の末尾から値を取り出す (pop)– リストの末尾の操作は厄介

Page 40: Deque with Haskel

Queue

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (push)– 列の末尾から値を取り出す (pop)– リストの末尾の操作は厄介– しかしデータ構造の申し子である皆さんな

ら対処法をすぐに思いつくはず

Page 41: Deque with Haskel

有名なことわざ

QueueはStack2つで作れる

Page 42: Deque with Haskel

Queue: 図示

● 空のQueueの下に2つのStackがあるじゃろ

Page 43: Deque with Haskel

Queue: 図示

● push(3)

3

3

Page 44: Deque with Haskel

Queue: 図示

● push(3), push(5)

3

3

5

5

Page 45: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1)

3

35

5

1

1

Page 46: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1), pop()

3

35

5

1

1

Page 47: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1), pop()● pop時右側が空だったらエイヤッする

3

35

5

1

1

Page 48: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1), pop()

3

35

5

1

1

Page 49: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1), pop()

5

5

1

1

Page 50: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1), pop(), push(2)

5

5

1

1

2

2

Page 51: Deque with Haskel

Queue: 図示

● push(3), push(5), push(1), pop(), push(2), pop()

5

5

1

1

2

2

Page 52: Deque with Haskel

Queue(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!

● 一番ややこしいのはpopするときに右側のStackが空だった時

Page 53: Deque with Haskel

Queue(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!

● 一番ややこしいのはpopするときに右側のStackが空だった時

351

Page 54: Deque with Haskel

Queue(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!

● 一番ややこしいのはpopするときに右側のStackが空だった時

351

エイヤッ

Page 55: Deque with Haskel

Queue(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!

● 一番ややこしいのはpopするときに右側のStackが空だった時

● Stackがただのリストであったことを思い出すと、エイヤッはただのリスト反転

– 標準で reverseという関数がある

Page 56: Deque with Haskel

Queue: 実装

(実装をここに書く)

(説明をここに書く)

Page 57: Deque with Haskel

Queue: 実装

Queue a = Q [a] [a]

Queueの型を定義 リスト2つ

Page 58: Deque with Haskel

Queue: 実装

Queue a = Q [a] [a]

push (Q xs ys) x = Q (x:xs) ys

push の実装 (Stackと同様)

Page 59: Deque with Haskel

Queue: 実装

Queue a = Q [a] [a]

push (Q xs ys) x = Q (x:xs) ys

pop (Q xs y:ys) = (y (Q xs ys))

右側が空じゃない時のpop

Page 60: Deque with Haskel

Queue: 実装

Queue a = Q [a] [a]

push (Q xs ys) x = Q (x:xs) ys

pop (Q xs y:ys) = (y (Q xs ys))pop (Q xs []) = pop(Q [] (reverse xs))

右側が空の時のpop

Page 61: Deque with Haskel

3つめのデータ構造

Deque

Page 62: Deque with Haskel

Deque

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (pushF)– 列の末尾に値を追加  (pushB)– 列の先頭から値を取り出す (popF)– 列の末尾から値を取り出す (popB)

Page 63: Deque with Haskel

Deque: 図示

● ここに空のDequeがあるじゃろ

– 左が先頭(Front), 右が末尾 (Back)

Page 64: Deque with Haskel

Deque: 図示

● pushF(3)

3

Page 65: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4)

3 4

Page 66: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5)

3 45

Page 67: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5), popB()

34

54

Page 68: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5), popB()

35

Page 69: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5), popB(), popF()

35

Page 70: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5), popB(), popF()

3

Page 71: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5), popB(), popF()pushB(4)

3 4

Page 72: Deque with Haskel

Deque: 図示

● pushF(3), pushB(4), pushF(5), popB(), popF()pushB(4), pushF(3)

3 433

Page 73: Deque with Haskel

Deque

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (pushF)– 列の末尾に値を追加  (pushB)– 列の先頭から値を取り出す (popF)– 列の末尾から値を取り出す (popB)

Page 74: Deque with Haskel

Deque

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (pushF)– 列の末尾に値を追加  (pushB)– 列の先頭から値を取り出す (popF)– 列の末尾から値を取り出す (popB)

Page 75: Deque with Haskel

Queue

● 次の操作に対応したデータ構造

– 列の先頭に値を追加  (pushF)– 列の末尾に値を追加  (pushB)– 列の先頭から値を取り出す (popF)– 列の末尾から値を取り出す (popB)

Page 76: Deque with Haskel

有名なことわざ

DequeはStack2つで作れる

Page 77: Deque with Haskel

Deque(Stack×2): 図示

● 空のDequeの下にStackが2つあるじゃろ

– 左が先頭(Front), 右が末尾 (Back)

Page 78: Deque with Haskel

432

Deque(Stack×2): 図示

● pushF(1), pushF(2), pushF(3), pushF(4)

4321

1

Page 79: Deque with Haskel

432

Deque(Stack×2): 図示

● pushF(1), pushF(2), pushF(3), pushF(4)popB()

4321

1

Page 80: Deque with Haskel

32

Deque(Stack×2): 図示

● pushF(1), pushF(2), pushF(3), pushF(4)popB()

4321

1エイヤッ

4

Page 81: Deque with Haskel

32

Deque(Stack×2): 図示

● pushF(1), pushF(2), pushF(3), pushF(4)popB()

4321

14

Page 82: Deque with Haskel

32

Deque(Stack×2): 図示

● pushF(1), pushF(2), pushF(3), pushF(4)popB()

321

1

Page 83: Deque with Haskel

Deque(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!(デジャヴ)

● 一番ややこしいのはpopするときにしたい方のStackが空だった時 (デジャヴ)

4321

Page 84: Deque with Haskel

321 4

Deque(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!(デジャヴ)

● 一番ややこしいのはpopするときにしたい方のStackが空だった時 (デジャヴ)

エイヤッ

Page 85: Deque with Haskel

Deque(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!(デジャヴ)

● 一番ややこしいのはpopするときにしたい方のStackが空だった時 (デジャヴ)

● エイヤッは空じゃないStackの中身を半分ずつにわける操作

– リストの最初 k 個分をとりだす take– リストの最初 k 個を除いたリストを得る drop– これらを使えば便利

Page 86: Deque with Haskel

Deque(Stack×2)

● Stackはさっき実装したばかりだしやるだけじゃん!(デジャヴ)

● 一番ややこしいのはpopするときにしたい方のStackが空だった時 (デジャヴ)

● エイヤッは空じゃないStackの中身を半分ずつにわける操作

– 空じゃない方の奥側半分を逆転して空の方につっこむ

Page 87: Deque with Haskel

Deque: 実装

(実装をここに書く)

(説明をここに書く)

Page 88: Deque with Haskel

Deque: 実装

Deque a = D [a] [a]

pushF (D xs ys) x = D (x:xs) yspushB (D xs ys) y = D xs (y:ys)

pushFとpushB (簡単)

Page 89: Deque with Haskel

Deque: 実装

Deque a = D [a] [a]

popF (D x:xs ys) = (x, (D xs ys))

左側が空じゃない時のpopF

Page 90: Deque with Haskel

Deque: 実装

Deque a = D [a] [a]

popF (D x:xs ys) = (x, (D xs ys))popF (D [] ys) = popF (D lh rh) where lh = take h ys rh = reverse (drop h ys) h = (length ys) `div` 2

左側が空の時のpopF

Page 91: Deque with Haskel

Deque: 実装

Deque a = D [a] [a]

popB (D xs y:ys) = (y, (D xs ys))popB (D xs []) = popB (D lh rh) where lh = reverse (drop h xs) rh = take h xs h = (length xs) `div` 2

popBも同様

Page 92: Deque with Haskel

クリックしてタイトルを挿入!

やったぜ

Page 93: Deque with Haskel

サンプルコード

● サンプルコードはこちら

● https://github.com/catupper/JOISS2015/blob/master/Queue/Deque.hs