生成赛事对阵图-排序
本文并非介绍框架设计。只是想通过这个案例,单地表述解决本文问题思路。
[TOC]
问题
有一个大区(跨服)玩法,各小区积分归总后的前16名可以参加后续的淘汰赛。
#已知
- 各个小区榜均已排序
- 归总后的数据长度>=16
解决
借鉴选择排序的思路,但由于各个集合本身有序,所以无需遍历各个集合求最大值。另外只需要归总后最高的16名,所以不需要对所有集合排序。
- 每次从N个有序集中,选出一个最大值
- 由于是有序集,后面的元素不可能比之前的大,所以已被选取的索引,之后不需要再被遍历,tOffsetMap记录各个集合最后的索引位置
Lua代码
math.randomseed(os.time())
local function sortset(s, n)
-- 初始化索引位置
local tOffsetMap = {}
for k, _ in pairs(s) do
tOffsetMap[k] = 1
end
local list = {}
for i = 1, n, 1 do
local iTargetKey = nil
for k, iOffset in ipairs(tOffsetMap) do
local l1 = s[k]
if l1 ~= nil then
-- 接着上次索引查找
local v1 =l1[iOffset]
if v1 ~= nil then
if iTargetKey == nil then
iTargetKey = k
else
local l2 = s[iTargetKey]
local v2 = l2[tOffsetMap[iTargetKey]]
if v2 ~= nil and v1 > v2 then
iTargetKey = k
end
end
end
end
end
if iTargetKey == nil then
-- 总数量不足n个,所以找不到最大值
break
end
-- 记录索引位置
table.insert(list, s[iTargetKey][tOffsetMap[iTargetKey]])
tOffsetMap[iTargetKey] = tOffsetMap[iTargetKey] + 1
end
return list
end
local function randSet()
local c1 = 10
local c2 = 20
local c3 = 9999
local list = {}
for i = 1, c1, 1 do
list[i] = {}
local rc2 = math.random(1, c2)
for j = 1, rc2, 1 do
local r = math.random(1, c3)
table.insert(list[i], r)
end
-- 保证集合有序
table.sort(list[i], function(a, b)
return a >= b
end)
end
return list
end
s = randSet()
local list = sortset(s, 16)
for _, v in ipairs(list) do
print(tostring(v) .. ',')
end
原文:
https://lizijie.github.io/2021/06/05/%E7%94%9F%E6%88%90%E8%B5%9B%E4%BA%8B%E5%AF%B9%E9%98%B5%E5%9B%BE-%E6%8E%92%E5%BA%8F.html
作者github:
https://github.com/lizijie
PREVIOUS生成赛事对阵图-洗牌