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
5.3k
Perlで学ぼう!文系プログラマのための、知識ゼロからのデータ構造と計算量
Shinpei Maruyama
August 21, 2015
Tweet
Share
More Decks by Shinpei Maruyama
See All by Shinpei Maruyama
過去や未来を扱うのは難しい? 過去と未来に立ち向かうための勘所
shinpeim
3
4.1k
設計ナイト2022 トランザクションスクリプト
shinpeim
12
3.6k
Ruby (off|with) the Rails
shinpeim
20
5.2k
綱渡りバッチ脱出大作戦
shinpeim
3
3.7k
Building native apps with scala.js
shinpeim
2
1.4k
今あえてDRY原則に向き合う
shinpeim
51
560k
Nekogata Drum Sequencer written in Scala.js
shinpeim
2
4k
複雑なJavaScriptアプリケーションに立ち向かうためのアーキテクチャ
shinpeim
36
15k
Using Scala.js with the JavaScript ecosystems
shinpeim
0
2.4k
Other Decks in Programming
See All in Programming
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
14
47k
NIKKEI Tech Talk#38
cipepser
0
350
ノーコードからの脱出 -地獄のデスロード- / Escape from Base44
keisuke69
0
140
AI 駆動開発におけるコミュニティと AWS CDK の価値
konokenj
5
310
Developer Joy - The New Paradigm
hollycummins
1
400
スマホから Youtube Shortsを見られないようにする
lemolatoon
27
34k
テーブル定義書の構造化抽出して、生成AIでDWH分析を試してみた / devio2025tokyo
kasacchiful
0
350
ボトムアップの生成AI活用を推進する社内AIエージェント開発
aku11i
0
1.4k
When Dependencies Fail: Building Antifragile Applications in a Fragile World
selcukusta
0
120
業務でAIを使いたい話
hnw
0
220
contribution to astral-sh/uv
shunsock
0
570
Google Opalで使える37のライブラリ
mickey_kubo
3
180
Featured
See All Featured
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Automating Front-end Workflow
addyosmani
1371
200k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
640
Optimizing for Happiness
mojombo
379
70k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Thoughts on Productivity
jonyablonski
72
4.9k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.7k
Keith and Marios Guide to Fast Websites
keithpitt
412
23k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.7k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3k
Building Adaptive Systems
keathley
44
2.8k
The Cost Of JavaScript in 2023
addyosmani
55
9.1k
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 高円寺ペンギンハウス • よろしくおねがいします
おしまい