# [TDD磕算法] 排序矩阵中找第n个数（一）隐喻的力量

1 2 4
4 6 8
5 7 9

### 初步尝试

1. 只有一个数字的矩阵

``````Given the matrix is:
|1|
Then I will get 1 at the 1 smallest element
``````

2. 2x2的矩阵，第2小的数字

``````Given the matrix is:
|1|2|
|3|4|
Then I will get 2 at the 2 smallest element

Given the matrix is:
|1|3|
|2|4|
Then I will get 2 at the 2 smallest element
``````

``````if (index == 1) { ... }
if (at(0,1) < at(1,0)) {
return at(0,1);
} else {
return at(1,0);
}
``````

4. 3x3矩阵，第3小的数字

``````Given the matrix is:
|1|2|3|
|4|5|6|
|7|8|9|
Then I will get 3 at the 3 smallest element
...
``````
``````if (index == 1) { ... }
if (index == 2) {
return Math.min(at(0,1), at(1,0));
}
return at(0,2);
``````

……
n. 取到第5个数字，分支越来越复杂，仍然没有重构出合适的结构

``````...
Given the matrix is:
|1|2|3|9|9|
|4|5|9|9|9|
|9|9|9|9|9|
|9|9|9|9|9|
|9|9|9|9|9|
Then I will get 5 at the 5 smallest element
...
Given the matrix is:
|1|2|3|9|9|
|4|9|9|9|9|
|5|9|9|9|9|
|9|9|9|9|9|
|9|9|9|9|9|
Then I will get 5 at the 5 smallest element
``````

``````if (index > size()) { return max(at(0,1), at(1,0)); }
if (index == 1) { return at(0,0); }
if (index == 2) { return min(at(0,1), at(1,0)); }
if (index == 3) {
if (at(1,0) > at(0,2)) { return at(0,2); }
if (at(0,1) > at(2,0)) { return at(2,0); }
return max(at(0,1), at(1,0));
}
if (index == 4) {
if (at(1,0) > at(0,3)) { return at(0,3); }
if (at(0,1) > at(3,0)) { return at(3,0); }
if (at(1,0) > at(0,2)) { return at(1,0); }
if (at(0,1) > at(2,0)) { return at(0,1); }
return min(at(0,2), at(2,0), at(1,1));
}
if (at(1,0) > at(0,4)) { return at(0,4); }
if (at(1,0) > at(0,3)) { return at(1,0); }
if (at(2,0) > at(0,3)) { return at(0,3); }
if (at(1,1) < at(0,2) || at(1,1) < at(2,0)) { return at(1,1); }
return max(at(2,0), at(0,2));
``````

http://cyber-dojo.org/review/show/91F6A9AFC1?avatar=lobster&was_tag=-1&now_tag=-1

### 重新思考

``````1,2,3
4,5,6
7,8,9
``````

``````1,4,7
2,5,8
3,6,9
``````

``````1,2,6
3,4,7
5,8,9
``````

### 以隐喻为模型重新实现

``````public int get(int index) {
if (index == 2) {
Integer result;
result = next();
result = next();
return result;
}
return at(0,0);
}
``````

``````@Test
public void should_get_smallest_from_avaliable_cells() {
//given
doReturn(new int[]{2,1,0,0,0}).when(retriever).rowRecords();
doReturn(5).when(retriever).at(0,2);
doReturn(4).when(retriever).at(1,1);
doReturn(6).when(retriever).at(2,0);
//when
int actual = retriever.next();
//then
verify(retriever).at(0,2);
verify(retriever).at(1,1);
verify(retriever).at(2,0);
verify(retriever).record(1,1);
assertEquals(4, actual);
}
``````

0 1 2 3 4
□ 5
□ 4
□ 6

■ 表示已经堆好的数字，□ 表示在这时新的数字可能堆在的位置。那么只需判断这几个点的数字大小就知道实际“堆”在了哪里。并且更新状态。比如这次next()取到数字4后，记录的状态变为。

0 1 2 3 4
□ 5
□ 6

``````protected Integer next() {
int[] rowRecords = rowRecords();
int row = 0;
int col = rowRecords[0];
Integer result = at(0, col);
for (int i = 1; i < rowRecords.length; i++) {
Integer candidate = at(i, rowRecords[i]);
if (result > candidate) {
result = candidate;
row = i;
col = rowRecords[i];
}
if (rowRecords[i] == 0) {
break;
}
}
record(row, col);
return result;
}

protected void record(int row, int col) {
rowRecords[row]=col+1;
}
``````

http://cyber-dojo.org/review/show/91F6A9AFC1?avatar=bee&was_tag=-1&now_tag=-1&filename=undefined

### 回顾

##### 附记

• 序言：七十年代末，一起剥皮案震惊了整个滨河市，随后出现的几起案子，更是在滨河造成了极大的恐慌，老刑警刘岩，带你破解...
沈念sama阅读 157,538评论 4 361
• 序言：滨河连续发生了三起死亡事件，死亡现场离奇诡异，居然都是意外死亡，警方通过查阅死者的电脑和手机，发现死者居然都...
沈念sama阅读 66,800评论 1 290
• 文/潘晓璐 我一进店门，熙熙楼的掌柜王于贵愁眉苦脸地迎上来，“玉大人，你说我怎么就摊上这事。” “怎么了？”我有些...
开封第一讲书人阅读 107,329评论 0 238
• 文/不坏的土叔 我叫张陵，是天一观的道长。 经常有香客问我，道长，这世上最难降的妖魔是什么？ 我笑而不...
开封第一讲书人阅读 43,725评论 0 203
• 正文 为了忘掉前任，我火速办了婚礼，结果婚礼上，老公的妹妹穿的比我还像新娘。我一直安慰自己，他们只是感情好，可当我...
茶点故事阅读 52,089评论 3 286
• 文/花漫 我一把揭开白布。 她就那样静静地躺着，像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上，一...
开封第一讲书人阅读 40,449评论 1 212
• 那天，我揣着相机与录音，去河边找鬼。 笑死，一个胖子当着我的面吹牛，可吹牛的内容都是我干的。 我是一名探鬼主播，决...
沈念sama阅读 31,758评论 2 311
• 文/苍兰香墨 我猛地睁开眼，长吁一口气：“原来是场噩梦啊……” “哼！你这毒妇竟也来了？” 一声冷哼从身侧响起，我...
开封第一讲书人阅读 30,448评论 0 195
• 序言：老挝万荣一对情侣失踪，失踪者是张志新（化名）和其女友刘颖，没想到半个月后，有当地人在树林里发现了一具尸体，经...
沈念sama阅读 34,152评论 1 239
• 正文 独居荒郊野岭守林人离奇死亡，尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
茶点故事阅读 30,432评论 2 244
• 正文 我和宋清朗相恋三年，在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
茶点故事阅读 31,933评论 1 258
• 序言：一个原本活蹦乱跳的男人离奇死亡，死状恐怖，灵堂内的尸体忽然破棺而出，到底是诈尸还是另有隐情，我是刑警宁泽，带...
沈念sama阅读 28,289评论 2 252
• 正文 年R本政府宣布，位于F岛的核电站，受9级特大地震影响，放射性物质发生泄漏。R本人自食恶果不足惜，却给世界环境...
茶点故事阅读 32,921评论 3 234
• 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹，春花似锦、人声如沸。这庄子的主人今日做“春日...
开封第一讲书人阅读 26,023评论 0 8
• 文/苍兰香墨 我抬头看了看天上的太阳。三九已至，却和暖如春，着一层夹袄步出监牢的瞬间，已是汗流浃背。 一阵脚步声响...
开封第一讲书人阅读 26,781评论 0 192
• 我被黑心中介骗来泰国打工， 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留，地道东北人。 一个月前我还...
沈念sama阅读 35,477评论 2 270
• 正文 我出身青楼，却偏偏与公主长得像，于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子，可洞房花烛夜当晚...
茶点故事阅读 35,381评论 2 263

### 推荐阅读更多精彩内容

• 黑盒测试案例设计技术篇 1 概述 本章介绍黑盒测试的概念和进行黑盒测试的目的与意义，及关于等价类划分、边界值分析、...
西边人阅读 16,471评论 0 41
• Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具（例如配置管理，服务发现，断路器，智...
卡卡罗2017阅读 134,095评论 18 139
• 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
中v中阅读 31,785评论 2 89
• 我庆幸，天神给我安排了一段缘，在孤冷的冬夜，让我遇见，一个柔美的女子。 只因偶然，奇妙的缘分，让开学一个月还没印象...
残殇千羽阅读 188评论 0 0
• 易效能189期复训队员---焦亚楠 人生无非四件事：读书，见人，行路，历事。本月关键字：团圆，幸福，学习 【2月的...
青春的阳光阅读 72评论 0 2