算法:在给定的操作方法内,如何用最少的步数将一个列表排序成另外一个大小相同的列表。

2017-02-11 16:45:53 +08:00
 TJT

起因

产品中有个用户排名列表(大小固定),于是有了个新的需求,这个列表要定时刷新,并且发生变化的用户高亮一下。 起初一看,不难嘛,位置变了就算发生变化了。但是有这种情况,有个用户突然插入到了列表的开头,那么对于剩下的用户来说,他们在列表中的位置都发生了变化,但这显然不符合常理,应该是只有刚插入的那个用户算是变化了,于是就展开了后面更复杂的情况。。。

可能的情况

旧列表 => 新列表 = {发生变化的下标集合}

  1. [1, 2, 3, 4, 5] => [1, 2, 3, 4, 9] = {4}
  2. [1, 2, 3, 4, 5] => [1, 2, 5, 4, 3] = {2, 4}
  3. [1, 2, 3, 4, 5] => [0, 1, 2, 3, 4] = {0}
  4. [1, 2, 3, 4, 5] => [3, 4, 5, 1, 2] = {3, 4}
  5. [1, 2, 3, 4, 5] => [0, 1, 4, 3, 2] = {0, 2, 4}
  6. [1, 2, 3, 4, 5] => [3, 1, 2, 4, 5] = {0}
    ...

方案 0

用排序算法,记录排序算法的对列表的所有修改,然后体现到界面上。在进一步优化可以针对数据特征来改进排序算法,但经过我们的讨论,这个方案很难接近最优解。

方案 1

定义以下操作

最后问题就是:如何用最少的操作来将 A 列表变成 B 列表

首先考虑的是穷举,但最后发现不能用穷举来解决,因为没有边界来确定是否已经穷举完所有可能,并且目前的情况下,可能性是无限的。

然后想到用 GP( https://en.wikipedia.org/wiki/Genetic_programming) 来接近最优解,但这个实现难度也不小。

问题

  1. 这个问题对应的是那个具体领域? Permutation or Sort algorithm?
  2. 有什么别的方法更简单粗暴?

最后

其实这个需求不是很重要,排名的变化是很有特征的,只要针对大部分出现的情况进行处理就好,就算没有处理到实际上也没什么影响。但这个问题本身我觉得是很有趣的,而且难度也不小,所以想看下大家对这个问题的解决思路,互相学习下~

先谢谢大家,第一次在 V2EX 发这么长的帖子,写的不好的地方请见谅。希望能看到脑洞大开的思路 XD

2255 次点击
所在节点    问与答
6 条回复
slixurd
2017-02-11 16:48:21 +08:00
Levenshtein distance?
TJT
2017-02-11 16:52:26 +08:00
@slixurd 谢谢!没有了解过这个,我研究下
aheadlead
2017-02-11 17:15:44 +08:00
看了几遍不是很明白
需要一些样例来说明

看标题立即就想到了 1#说的编辑距离
这是高中时的一道经典动态规划的题目

同建议看看 1#的内容
aheadlead
2017-02-11 17:16:36 +08:00
看了几遍不是很明白,需要一些样例来说明。看标题立即就想到了 1#说的编辑距离,这是高中时的一道经典动态规划的题目。同建议看看 1#的内容。
TJT
2017-02-11 17:25:14 +08:00
@aheadlead 嗯,谢谢,我已经试着用 Levenshtein distance 的算法来实现这个需求了。另外是 #可能的情况 里面的样例不够直观导致你不是很明白吗?
Exin
2017-02-11 18:58:42 +08:00
参考下 git diff 这种功能的思路?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/339775

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX