Lua 排行榜更新

排行榜:

key:玩家名字,val:玩家的数值

1 local key1 = {"a1", "a2", "b1", "b2", "a3"}
2 local val1 = {1, 3, 5, 7, 9}
3 local key2 = {"b1", "a1", "a2", "b2"}
4 local val2 = {2, 4, 6, 8}

val1:原排行榜中的数值,已排序(从小到大)

key1:原排行榜val已排序的数值对应的名字

key2, val2为新的数据,两组数据合并为一组,相同名字的数值合并取最小(或最大)

采用归并排序

迭代法步骤:

1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置

3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4. 重复步骤3直到某一指针达到序列尾

5. 将另一序列剩下的所有元素直接复制到合并序列尾

递归法

原理如下(假设序列共有n个元素):

  1. 将序列每相邻两个数字进行归并操作,形成floor(n/2)个序列,排序后每个序列包含两个元素
  2. 将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
  3. 重复步骤2,直到所有元素排序完毕

动态图:

归并排序

又因旧排行榜数据和新排行榜数据已经是两个已经有序的数列,就不用再分了。但需要合并相同名字的数据只保留一份

使用协程合并:

 1 local keys, vals = {}, {}
 2 -- 创建协程
 3 local function createCo(keys, values)
 4     return coroutine.create(
 5         function ()
 6             for i, v in ipairs(values or {}) do
 7                 coroutine.yield(keys[i], v)
 8             end
 9         end
10         )
11 end
12 -- 插入到结果中并唤醒协程
13 local function insertResultAndResume(key, val, co)
14     for _, v in next, keys do
15         if v == key then
16             return coroutine.resume(co)
17         end
18     end
19     table.insert(keys, key)
20     table.insert(vals, val)
21     return coroutine.resume(co)
22 end
23 local co1, co2 = createCo(key1, val1), createCo(key2, val2)
24 local r1, k1, v1 = coroutine.resume(co1)
25 local r2, k2, v2 = coroutine.resume(co2)
26 
27 while v1 and v2 do
28     if v1 > v2 then
29         r2, k2, v2 = insertResultAndResume(k2, v2, co2)
30     else
31         r1, k1, v1 = insertResultAndResume(k1, v1, co1)
32     end
33 end
34 while v1 do
35     r1, k1, v1 = insertResultAndResume(k1, v1, co1)
36 end
37 while v2 do
38     r2, k2, v2 = insertResultAndResume(k2, v2, co2)
39 end
40 
41 print("-------result--------")
42 for i, v in pairs(keys) do
43     print(v, "= ", vals[i])
44 end
View Code

-- 打印结果为:

-------result--------
a1    =     1
b1    =     2
a2    =     3
b2    =     7
a3    =     9
原文地址:https://www.cnblogs.com/YYRise/p/6109606.html