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
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
1
600
テストコード文化を0から作り、変化し続けた組織
kazatohiei
2
1.5k
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
230
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
540
rails statsで大解剖 🔍 “B/43流” のRailsの育て方を歴史とともに振り返ります
shoheimitani
2
930
フロントエンドのディレクトリ構成どうしてる? Feature-Sliced Design 導入体験談
osakatechlab
8
4.1k
Security_for_introducing_eBPF
kentatada
0
110
From Translations to Multi Dimension Entities
alexanderschranz
2
130
ソフトウェアの振る舞いに着目し 複雑な要件の開発に立ち向かう
rickyban
0
890
Scalaから始めるOpenFeature入門 / Scalaわいわい勉強会 #4
arthur1
1
310
Refactor your code - refactor yourself
xosofox
1
260
Fibonacci Function Gallery - Part 1
philipschwarz
PRO
0
210
Featured
See All Featured
Unsuck your backbone
ammeep
669
57k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
We Have a Design System, Now What?
morganepeng
51
7.3k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
29
2k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
127
18k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.5k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.4k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.3k
The World Runs on Bad Software
bkeepers
PRO
65
11k
Docker and Python
trallard
42
3.1k
A better future with KSS
kneath
238
17k
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 高円寺ペンギンハウス • よろしくおねがいします
おしまい