はじめに
「Cの次に重い人は誰?」
この質問、なんとなく答えられそうな気がしませんか? でも、ちゃんと説明しようとすると、意外と難しい。
この記事では、「次」という言葉が考えるときにどう働くのかを、できるだけかみくだいて説明してみます。数式やSQLも出てきますが、雰囲気だけつかんでもらえれば大丈夫です。
1. 「次」がはっきり決まる世界、決まらない世界
数字の世界の「次」
1, 2, 3, ... という整数の世界では、「次」は迷いようがありません。1の次は2、2の次は3。誰が計算しても同じ答えになります。
これを数学っぽく言うと、後者関数(Successor function)というものを使って $S(n) = n + 1$ と書けます。難しく聞こえるかもしれませんが、要するに「1個先に進む」というだけのことです。
身近な例:レンチのサイズ
工具のレンチ(スパナ)のサイズを思い浮かべてください。
8mm, 10mm, 12mm, 13mm, 14mm, 17mm, 19mm...
「10mmの次に大きいレンチは?」と聞かれたら、答えは12mmですよね。これは規格として並んでいる順番の中で、1つ先に進んでいるからです。
ここで大事なポイントがあります。レンチの太さ自体は本来連続的な値(作ろうと思えば10.1mmでも10.5mmでも作れます)ですが、「規格品として並んでいる」からこそ「次」がはっきり決まるのです。
では「体重が次に重い人」は?
さて本題です。次のような5人がいるとします。
| 名前 | 体重 |
|---|---|
| A | 55.4 kg |
| B | 60.0 kg |
| C | 70.2 kg |
| D | 80.1 kg |
| E | 90.2 kg |
「Cの次に重い人は?」と聞かれたら、答えはBです。
なぜでしょうか? 体重は連続的な値なので、レンチのような決まった規格はありません。でも、この5人を体重の重い順に並べてみると、話が変わってきます。
| 順位 | 名前 | 体重 |
|---|---|---|
| 1位 | E | 90.2 kg |
| 2位 | D | 80.1 kg |
| 3位 | C | 70.2 kg |
| 4位 | B | 60.0 kg |
| 5位 | A | 55.4 kg |
こうして順番をつけてしまえば、あとは「3位の次=4位」というだけの話になります。4位はB、というわけです。
つまりやっていることは、
- 体重が重い順に全員を並べる
- Cが何位か確認する(3位)
- その1つ下の順位を見る(4位)
- 4位の人を答える(B)
という4ステップです。体重そのものを直接計算しているわけではなく、いったん「順番」というものさしに置き換えてから「1つ先」を探しているんですね。
2. なぜ体重そのものには「次」がないのか
もう少し掘り下げてみます。
70.2kgより重い実数(小数を含む数)は無限にあります。70.3kgかもしれないし、70.21kgかもしれないし、70.2000001kgかもしれません。どれだけ細かく考えても、その間にさらに細かい数字が入り込む余地があります。
このように、数字と数字のあいだにどこまでも別の数字が挟まる性質を、稠密性(ちゅうみつせい)と呼んだりします。名前は難しいですが、「どんな2つの数字の間にも、まだ別の数字を入れられる」というだけのことです。
だから「70.2kgの次の重さ」と言われると、決めるのがとても難しい。70.2001kgなのか70.20001kgなのか、いくらでも細かくできてしまうので。
「次」が意味を持つのは、あくまで人間が「順位」という区切りを作ったあとの話、というわけです。
3. 「より重い」と「次に重い」はまったく違う
ここが一番混同しやすいポイントです。
「Cより重い人」と聞かれたら
条件は「Cより体重が大きい」というだけです。この条件に当てはまるのはDとEの2人。どちらを答えても間違いではありません。答えが1人に決まらないんです。
「Cの次に重い人」と聞かれたら
こちらは「Cより軽い人たちの中で、一番Cに近い(=一番重い)人」を指します。当てはまるのはBだけです。
つまり、
- 「より重い」:条件に合う人を全員集めてくる作業(絞り込み)
- 「次に重い」:並び替えたリストの中で1つ隣を見る作業(隣を探す)
この2つはまったく別の作業をしているのに、日本語ではどちらも似たような言い回しになるので混同しやすいんですね。
4. 「重い順」は、なぜ重い方から並べるのか?
「重さ」は単なる数値です。
70 kg、80 kg、90 kgという数字そのものには、「次に進む」という方向はありません。
しかし、
Cの次に重い人
と言われた場合、私たちは自然に「重い順」という並びを想定します。
例えば、5人の体重を重い順に並べると以下のようになります。
| 順位 | 対象 | 重量 |
|---|---|---|
| 1位 | E | 90.2 kg |
| 2位 | D | 80.1 kg |
| 3位 | C | 70.2 kg |
| 4位 | B | 60.0 kg |
| 5位 | A | 55.4 kg |
この並びなら、「Cの次に重い人」は「Cの次の順位にいる人」と考えることができます。
Cは3位なので、次は4位です。
$$3 + 1 = 4$$
したがって答えは B です。
ここで重要なのは、「重い」という言葉そのものが順位を指定しているのではなく、「次に重い」という表現によって、重さを基準にした順序を作る必要が生じるということです。
「次」が出てきたら、まず順序を作る
「Cの次に重い人」という問いを見たら、いきなり「Cより重い人は誰か?」と考えてはいけません。
まず、「何の順序における次なのか?」を考えます。
この場合は「重さ」を基準にした順序です。
「Cの次に重い人」
↓
重さを基準に並べる
↓
重い順にソート(降順)
↓
Cの順位を確認
↓
次の順位を見る(+1)
↓
「B」
「次」という言葉が出てきた時点で、単純な大小比較ではなく、順序の中での位置を求める問題として扱います。
あえて「軽い順」にすると何が起こるか
もちろん、同じデータを軽い順(昇順)に並べても、数学的には問題を解くことができます。
[昇順:軽い順]
Index 0: A 55.4 kg
Index 1: B 60.0 kg ← 目的の要素
Index 2: C 70.2 kg ← 基準点
Index 3: D 80.1 kg
Index 4: E 90.2 kg
しかし、「Cの次に重い人」を求める場合には、少し不自然な操作になります。
Cは Index 2 にいますが、答えの B は Index 1 です。
つまり、「次」と言っているのに位置番号を1つ減らす($2 \to 1$)必要があります。
ここには2つの逆転が発生しています。
-
第1の逆転:並び順と「重い」の方向が逆になる
「次に重い人」を探しているのに、データは軽い順に並んでいます。そのため、重い方向を意識しながら配列を逆向きにたどる必要があります。 -
第2の逆転:「次」なのに位置を1つ戻す
通常、「次」は $n \to n + 1$ と考えられます。ところが軽い順のリストでは $2 \to 1$ となり、「次」という自然言語と実際の位置の移動方向が逆になります。
目的に合った並べ方をして、順序通りに見て次を決めるのが最も間違いにくいと思います。
「Cの手前の軽い人」とは言わない
この違いは、自然言語に戻してみるとさらに分かりやすくなります。
軽い順に並べた場合、BはCの「1つ前」にあります。
A → B → C → D → E
↑
ひとつ前
しかし、Bを説明するために 「Cの手前にいる軽い人」 と言うのは不自然です。また、「Cの直前で一番重い人」 と言っても、「直前」がどの順序を基準にしているのか分かりにくくなります。
一方、重い順に並べれば、
E → D → C → B → A
↓
Cの次に重い
となり、「Cの次に重い人」 という自然言語と、データ上の「次の位置」がそのまま一致します。
「次」とソート方向を一致させる
したがって、「次」を扱うときには、自然言語で考えている「次」と、データ上の次の位置を一致させることが重要です。
「Cの次に重い人」なら、重い順に並べれば、
- 1位: E
- 2位: D
- 3位: C
- 4位: B ← 次
- 5位: A
となり、$S(3) = 4$ という後者関数をそのまま適用できます。
逆に軽い順にすると、
- 1位: A
- 2位: B ← 次に重い
- 3位: C
- 4位: D
- 5位: E
となり、「次」という言葉に対して「1つ前の要素」を参照することになります。
このような方向の逆転は、人間が考える場合にも、プログラムやAIが処理する場合にも混乱の原因になります。
- 「次」という言葉が出てきたら、まず「何の順序における次なのか」を確定する。
- 可能なら、その「次」が位置番号の $+1$ になるように並べ替える。
これが、「Cの次に重い人」のような問題をシンプルに扱うための基本的な考え方です。
$$\boxed{\text{「次」という指示} \longrightarrow \text{基準となる順序を決める} \longrightarrow \text{並べ替え} \longrightarrow \text{順位を1つ進める(+1)}}$$
5. 英語で言うとどうなる?
英語で表現すると、この違いがもっとはっきりします。
「Cより重い」 $\rightarrow$ heavier than C
これは単なる不等号の条件なので、D, Eどちらも当てはまります。1人には決まりません。
「Cの次に重い」 $\rightarrow$ the next heaviest person after C
こちらは heaviest(最上級) が使われているのがポイントです。「Cより軽い人たちの中で、一番重い人」という意味あいになるので、最上級がぴったりハマるわけです。
日本語で「次に重い」と言うと一見比較級っぽく聞こえますが、実際にやっている操作は「絞り込んでから一番大きいものを選ぶ」という最上級的な操作なんですね。
6. SQLで書くとこうなる(エンジニア向けおまけ)
ここからはちょっと技術寄りの話なので、興味のある方だけどうぞ。
やり方1: 順位をつけてから1つずらす
WITH RankedUsers AS (
SELECT
name,
weight,
ROW_NUMBER() OVER (ORDER BY weight DESC) AS position
FROM users
)
SELECT name, weight
FROM RankedUsers
WHERE position = (
SELECT position + 1
FROM RankedUsers
WHERE name = 'C'
);
先に全員に順位をつけてしまって、Cの順位 + 1 の人を探す、という発想です。
やり方2: 絞り込んでから一番上を取る
SELECT name, weight
FROM users
WHERE weight < (
SELECT weight
FROM users
WHERE name = 'C'
)
ORDER BY weight DESC
LIMIT 1;
「Cより軽い人」に絞り込んでから、その中で一番重い人(=先頭)を1人だけ取る、というやり方です。降順(重い順)に並べてから先頭を取る、というのがポイントです。
※ 同率(同じ体重の人)がいたらどうする?
もし「Cと同じ体重の人」や「まったく同じ体重の2人組」が存在する場合、SQLではROW_NUMBER()(連番)を使うか、RANK()/DENSE_RANK()(同順位を許容)を使うかによって挙動が変わります。「次」を厳密に定義するには、「同じ値のときの優先順位ルール(ID順など)」を決めておく必要があります。
まとめ
| 聞かれ方 | やっていること |
|---|---|
| より重い人 | 条件に合う人を全部集める(絞り込み) |
| 一番重い人 | 全体の中の最大値を探す |
| 次に重い人 | 絞り込んだ中の最大値を探す(隣を探す) |
体重のような連続した値そのものには、本来「次」というものは存在しません。でも、順位という区切りに置き換えることで、初めて「次」がはっきり決まるようになります。
「次に重い人は?」と聞かれて迷ったら、
- まず並び替える
- それから1つ隣を見る
この2つを分けて考えるだけで、もう迷わなくなります。