1. [1,2,3,1,4] capacity=3 -> 4 miss
  2. [1,2,1,2] capacity=2 -> 2 miss
  3. [1,2,3,4,5] capacity=2 -> 5 miss
  4. [7,0,1,2,0,3,0,4] capacity=3 -> 6 miss
  5. 全て同じ -> 1 miss
コース一覧
コンピューターサイエンス入門:理論編
LRU 簡易シミュレーション

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

LRU 簡易シミュレーション

手元に置ける量は決まっています。空きが無いのに新しいものを置きたくなったら、何かを捨てるしかありません。問題は、どれを捨てるかです。選び方ひとつで、次に取りに行く回数が変わります。

全部は載らない

メモリは有限なので、OS はディスク上のページを必要な分だけメモリに載せます。載っていないページを触ると、そこで一度止まってディスクから読み直しになります。これがページフォルトで、キャッシュで言う miss です。載せられる枚数を増やせない以上、どれを追い出すかの判断がそのまま速さになります。

どれを捨てるかで、次に困る回数が変わる

LRU は Least Recently Used の略で、一番長いあいだ使われていないものを捨てる決め方です。根拠は経験則で、しばらく触っていないものはこの先も当分触られない、という観察に立っています。容量 2 で A B A C B の順に触ると、次のように動きます。

プレーンテキスト

A 無い [A] B 無い [A B] A あった [B A] 使ったので A が新しくなる C 無い [A C] 一番古い B を捨てる B 無い [C B] さっき捨てた B をまた取りに行く

外れたのは 4 回です。3 手目で A を使っていなければ、捨てられるのは A だったので、その後の流れは変わっていました。過去の使われ方が、未来の捨て方を決めています。

この決め方は、名前を変えていろいろな場所に住んでいます。Redis の追い出し方針、ブラウザが持っている画像の控え、スマホで裏に回したアプリが落とされる順番も、おおむね同じ考え方です。

使っただけでも順番は動く

ここが一番間違えやすいところです。新しく入れたときだけ順番を更新すると、それは先に入れたものから捨てる決め方になり、名前だけ LRU の別物になります。すでに手元にあるものを使ったときにも、今使った、と記録し直します。列のいちばん後ろへ移す操作は、いったん抜いてから足すだけです。

Python

recent = ["report", "budget", "memo"] # 左が古い recent.remove("budget") recent.append("budget") print(recent) # ['report', 'memo', 'budget']

JavaScript

const recent = ["report", "budget", "memo"]; recent.splice(recent.indexOf("budget"), 1); recent.push("budget");

配列で書くと、探すたびに端から見ていくことになります。学ぶあいだはこれで十分ですが、本物の OS や Redis は、連想配列と双方向のリストを組み合わせて、探す手間を一定にしています。

容量が足りないと、何を捨てても外れる

同時に触りたいものの数が、置ける枚数より多いときは、どんな決め方をしても毎回外れます。1 2 3 を繰り返し触るのに 2 枚しか置けない状態がそれで、追い出した直後にまたそれを取りに行く堂々巡りになります。追い出し方を変える前に、置ける量が足りているかを疑います。

要件

  1. lruMisses という名前の関数を実装すること
  2. LRU 方式でミス回数を正しく数えること
  3. ヒットしたページもキャッシュ内で最新に更新すること

入出力例

lruMisses([1,2,3,1,4], 3) → 4 lruMisses([1,2,1,2], 2) → 2 lruMisses([1,2,3,4,5], 2) → 5 lruMisses([7,0,1,2,0,3,0,4], 3) → 6 lruMisses([5,5,5,5], 3) → 1

ヒント

cache を配列で持ち、先頭が古い・末尾が新しいとする

hit のときは要素を一度削除して末尾に追加し直す

miss のとき容量超過なら先頭を pop する

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • エンディアンの入れ替え (uint32)

    32bit 整数のバイト順を入れ替えてビッグエンディアンとリトルエンディアンを変換する

  • バッファ範囲チェック

    オフセットと長さが固定サイズバッファに収まるかを判定する

  • 第5章まとめクイズ

    バイト・KB変換、キャッシュ、LRU、エンディアン、バッファ範囲を総復習する4択クイズ

  • Base64 エンコード後の長さ計算

    バイト列を Base64 エンコードしたときの文字数を、入力長から数式で求める関数を作ります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • メモリプログラムとデータを一時保持する高速領域
  • キャッシュ一度取得したデータを再利用するための一時保存
  • 判断YES/NO 分岐を表す菱形
  • ブラウザユーザーから見たWebのクライアント
  • 配列サイズ固定の同型データの集まり
  • リスト順序付きで複数の値を扱うデータ構造
  • 関数処理に名前を付けて再利用できる単位
main.py
学習モード
エディタを読み込んでいます

メモ

LRU 簡易シミュレーション

⌘S で保存