Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Perlで学ぼう!文系プログラマのための、知識ゼロからのデータ構造と計算量
Search
Shinpei Maruyama
August 21, 2015
Programming
3
5k
Perlで学ぼう!文系プログラマのための、知識ゼロからのデータ構造と計算量
Shinpei Maruyama
August 21, 2015
Tweet
Share
More Decks by Shinpei Maruyama
See All by Shinpei Maruyama
過去や未来を扱うのは難しい? 過去と未来に立ち向かうための勘所
shinpeim
3
3.5k
設計ナイト2022 トランザクションスクリプト
shinpeim
11
3.4k
Ruby (off|with) the Rails
shinpeim
20
5k
綱渡りバッチ脱出大作戦
shinpeim
3
3.4k
Building native apps with scala.js
shinpeim
2
1.3k
今あえてDRY原則に向き合う
shinpeim
51
560k
Nekogata Drum Sequencer written in Scala.js
shinpeim
2
3.9k
複雑なJavaScriptアプリケーションに立ち向かうためのアーキテクチャ
shinpeim
36
15k
Using Scala.js with the JavaScript ecosystems
shinpeim
0
2.2k
Other Decks in Programming
See All in Programming
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
330
The rollercoaster of releasing an Android, iOS, and macOS app with Kotlin Multiplatform | droidcon Italy
prof18
0
150
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
110
Discord Bot with AI -for English learners-
xin9le
1
120
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
180
テスト自動化失敗から再挑戦しチームにオーナーシップを委譲した話/STAC2024 macho
ma_cho29
1
1.3k
htmxって知っていますか?次世代のHTML
hiro_ghap1
0
330
KMP와 kotlinx.rpc로 서버와 클라이언트 동기화
kwakeuijin
0
140
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
テストケースの名前はどうつけるべきか?
orgachem
PRO
0
130
CSC509 Lecture 14
javiergs
PRO
0
130
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
200
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.2k
Producing Creativity
orderedlist
PRO
341
39k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Bash Introduction
62gerente
608
210k
Building an army of robots
kneath
302
44k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
Making Projects Easy
brettharned
116
5.9k
Transcript
by しんぺい a.k.a. 猫型蓄音機 Perlで学ぼう! 文系プログラマのための 知識ゼロからの データ構造と計算量
あんただれ • しんぺいとか猫型とかいう名前で呼 ばれています • rerakuという会社で働いてます • 仕事ではScala, Perl, Ruby
あんただれ • Github:Shinpeim • process-book • 新潟非在住 Niigata.pm 主催です •
趣味でバンド • 11/14高円寺ペンギンハウス
ペンギンハウス
ペンギンハウス
今日やること • データ構造と計算量について、簡単 に解説します • 基本的なことしかやりません • ハイレベルプログラマ諸氏は今すぐ 別の部屋で有意義な時間を過ごすん だ!!
事前準備
Cの変数とメモリ
何がおきてる?
int のメモリを確保 JOUB
1を代入 JOUB
bも同様に JOUB JOUC
c も同様に JOUD JOUB JOUC
CPUが足し算してcに代入 JOUD JOUB JOUC
ポイント • 変数は箱ではない!!!!!! • メモリです • たくさん用意すれば用意するほどメ モリを消費する
メモリとポインタ
何がおきてる?
実はメモリには番地があります B 10000番
番地を取得 B 10000番
番地を保存する4byte確保 TIPSU C B 10000番
番地を代入 TIPSU C B 10000番
bの中身を10進数で表示 TIPSU C B 10000番
bの番地の指し示す先を見て 10000番 TIPSU C B
short* なので2バイト読む TIPSU C B
ポイント • ポインタの中には「メモリ上の位置」を 表す数字が入ってる • その数字の番地から、ポインタが示す型 のバイト数だけ読めばポインタの指す値 を読むことができる • こうやって「値につながる値」を作るこ
とができる
練習問題 へんな値が出力されるのはなぜ?
Perlの場合
何がおきてる?
SVを確保 47
AVを確保 47 "7
HVを確保 47 "7 47 )7 B
SVを確保してSVの場所を代入 47 "7 47 )7 47 B
47 47 SFG YGEEC 0x7f99d080db78
中身を表示 47 "7 47 )7 47 B
47 47 SFG YGEEC
中身の指し示すやつを取ってきて表示 47 "7 47 )7 47 B
47 47 SFG YGEEC 0x7f99d080db78
ポイント • 値はメモリに確保されてる • リファレンスにはそのメモリの場所 を示すものが入っている • ねっ、CもPerlも変わらないでしょ
さまざまな データ構造
エントリーナンバー1
配列
なにがおきてる?
short5個分を「連続して」確保 10000番
変数名でアクセスすると番地が取れる 10000番
添え字付きアクセス 10000 + short(2byte) *
2 番地を読みに行くよ 10000番
添え字付きアクセス
配列の要素を増やしたい
エントリーナンバー2
単方向連結リスト
単方向連結リストの要素 a next element
単方向連結リスト
要素一個つくる 要素一個つくる
要素一個つくる )7 @WBMVF @OFYU@SFGVOEFG 1
要素一個つくる )7 @WBMVF @OFYU@SFGVOEFG FM@ &MFNFOU SFG 1
ふたつめの要素作る )7 @WBMVF @OFYU@SFGVOEFG FM@ &MFNFOU SFG )7
@WBMVF @OFYU@SFG&MFNFOU SFG FM@ &MFNFOU SFG 1 2
$el_ 1もう出てこないので無視 )7 @WBMVF @OFYU@SFGVOEFG )7 @WBMVF @OFYU@SFG&MFNFOU
SFG FM@ &MFNFOU SFG 1 2
同様にみっつめの要素 )7 @WBMVF @OFYU@SFGVOEFG )7 @WBMVF @OFYU@SFG&MFNFOU SFG
FM@ &MFNFOU SFG )7 @WBMVF @OFYU@SFG&MFNFOU SFG 1 2 3
Listの実装 コンストラクタ リストの先頭に 値を追加するメソッド
空のリストを作って )7 @pSTU@FMFNFOU VOEFG MJTU -JTU SFG
要素をひとつ挿入 )7 @pSTU@FMFNFOU VOEFG MJTU -JTU SFG )7
@WBMVF @OFYU@SFGVOEFG
要素をひとつ挿入 )7 @pSTU@FMFNFOU &MFNFOUSFG MJTU -JTU SFG )7
@WBMVF @OFYU@SFGVOEFG
2を挿入 MJTU -JTU SFG )7 @WBMVF @OFYU@SFGVOEFG )7
@pSTU@FMFNFOU &MFNFOUSFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG
3つめの値を取得したい MJTU -JTU SFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG
)7 @pSTU@FMFNFOU &MFNFOUSFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7 @WBMVF @OFYU@SFGVOEFG
MJTU -JTU SFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7
@pSTU@FMFNFOU &MFNFOUSFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7 @WBMVF @OFYU@SFGVOEFG 3つめの値を取得したい
MJTU -JTU SFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7
@pSTU@FMFNFOU &MFNFOUSFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7 @WBMVF @OFYU@SFGVOEFG 3つめの値を取得したい
MJTU -JTU SFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7
@pSTU@FMFNFOU &MFNFOUSFG )7 @WBMVF @OFYU@SFG &MFNFOUSFG )7 @WBMVF @OFYU@SFGVOEFG 3つめの値を取得したい
ポイント • メモリアドレスが飛び飛び • 「空いてるところ」にメモリ確保で きる • 先頭からの順々に辿らないといけな いので一発でアクセスできない
一発とか順々とか ちょっと ふわっとしてる もうちょっと ちゃんと言いたい
ここで ちょっと寄り道 計算量の話
オーダー法 • データの数がn個のとき、n回計算を しないといけないとき、O(n)という • 2n回計算しないといけない、とか、 2n + a回計算しないといけないとき もO(n)という
• 要するに定数倍とか定数項は考えない
連結リストの計算量 • n個めの要素にアクセスしたい • 最初の要素へのアクセス + n - 1回辿 る必要がある
= O(n) • リストの最初に値を挿入したい • 後ろにいくつ要素があっても、最初の要 素へのアクセス + 新しい要素を作って つなぐだけ = O(1)
配列の計算量 • n個めの要素にアクセスしたい • 計算で一発でメモリ番地が出せて、そこ を読むだけでよい • O(1)
いろんな計算量を グラフでみると 特徴がわかる
O(n) ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ
O(n) ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ
O(n^2) ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ
O(n^2) ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ
O(1) ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ
O(log n)
O(log n) ԣ࣠ɿσʔλͷݸ ॎ࣠ɿܭࢉͷྔ
ポイント • オーダー法は「正確な計算量」を導 かない • データの量に応じて、「データが増 えたときにどれくらい処理量が増え るか」をざっと知るための指標です
データ構造の話に 戻ります
連結リストの特徴 • 探索の計算量がO(n)だった • 悪くないけどO(log n)だと嬉しい ですよねー
エントリーナンバー3
2分木
2分木のnode a x<a a<x
)7 @SPPUVOEFG USFF 5SFFSFG tree 空の2分木
)7 @SPPUVOEFG USFF 5SFFSFG tree 2分木に最初の値:4を追加
2分木に最初の値:4を追加 )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @SPPU/PEF SFG
USFF 5SFFSFG tree
2分木に2を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFSVOEFG )7 @SPPU/PEF
SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に2を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFSVOEFG )7 @SPPU/PEF
SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に2を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFSVOEFG )7 @SPPU/PEF
SFG USFF 5SFFSFG V )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に6を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFSVOEFG )7 @SPPU/PEF
SFG USFF 5SFFSFG V )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に6を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFSVOEFG )7 @SPPU/PEF
SFG USFF 5SFFSFG V )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に6を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFS/PEFSFG )7
@SPPU/PEF SFG USFF 5SFFSFG V V )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に3を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFS/PEFSFG )7
@SPPU/PEF SFG USFF 5SFFSFG V V )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG tree
2分木に3を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFS/PEFSFG )7
@SPPU/PEF SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG V V tree
2分木に3を追加 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFS/PEFSFG )7
@SPPU/PEF SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFS/PEFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG V V V tree
2分木から1を探索 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFS/PEFSFG )7
@SPPU/PEF SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFS/PEFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG V V V tree
2分木から1を探索 )7 @WBMVF @TNBMMFS/PEFSFG @MBSHFS/PEFSFG )7
@SPPU/PEF SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFS/PEFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG V V V tree
2分木の探索 • 4つ要素があるけど2回で済んだ • こういう風にちゃんと「ばらけた」 木になってるとO(log n)になる
2分木から5を探索 )7 @WBMVF @TNBMMFSVOEFG @MBSHFS/PEFSFG )7 @SPPU/PEF
SFG USFF 5SFFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFS/PEFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFS/PEFSFG )7 @WBMVF @TNBMMFSVOEFG @MBSHFSVOEFG
2分木の探索 • 実質連結リスト • O(n)じゃん
エントリーナンバー4
B木
B木のnode b a x<a a<x<b b<x
空のB木に7を追加
B木に3を追加
B木に9を追加 満員じゃん
B木に9を追加 全員並べて
B木に9を追加 nodeふたつに分けて
B木に9を追加 nodeふたつに分けて
B木に9を追加 真ん中の値の行き場がない
B木に9を追加 新しいnode作る
B木に9を追加 枝つなぐ
B木に9を追加 見やすいように整列!
B木に5を追加
B木に6を追加 満員じゃん
B木に6を追加 全員並べて
B木に6を追加 nodeふたつに分けて
B木に6を追加 真ん中は上に空きがあるのでそこに入れる
B木に6を追加
B木に6を追加 枝つなぎ直す
B木に6を追加 見やすいように整列!
B木に10を追加
B木に16を追加 満員じゃん
B木に16を追加 真ん中は上に
B木に16を追加 満員じゃん
B木に16を追加
B木に16を追加 node分割して 枝つなぎ直す
B木に16を追加 新しいnode作って 枝つなぐ
B木に16を追加
B木に16を追加 O(log n)
O(m)
エントリーナンバー5
B+木
B+木 • DBのインデックスとかに使われて る • B木の改良版 • 末端のnodeに全部のデータが入っ てる •
node同士がlinkされてることが多い
B+木
B+木から5を探索
select * from table where id > 5
まとめ
まとめ • データ構造と計算量について簡単に 見てみました • この程度の理解でも、ふだんの業務 に活かせることは増えます • 今後の学習や業務に活かしていただ ければ幸いです
最後に • 11/14 高円寺ペンギンハウス • よろしくおねがいします
おしまい