Lua中如何按自定义字符串表的指定顺序对另一字符串表排序
Lua按指定顺序排序字符串表的修改方案
原有代码的适配修改
你现有移植的代码本身不需要修改比较逻辑,因为Lua的>、==运算符原生支持字符串的字典序比较,数字和字符串的比较逻辑通用。仅需要修复一个索引偏移的bug即可支持字符串排序:
原有代码中输出索引ind初始值为0,赋值时直接使用A1[ind]会把第一个元素存在索引0的位置,而Lua数组默认从1开始遍历,会导致第一个元素丢失。修改索引赋值逻辑即可,修改后的完整代码如下:
function first(arr, low, high, x, n) if high >= low then local mid = low + math.floor((high - low) / 2) if (mid == 1 or x > arr[mid - 1]) and arr[mid] == x then return mid end if x > arr[mid] then return first(arr, (mid + 1), high, x, n) end return first(arr, low, (mid - 1), x, n) end return nil end function sortAccording(A1, A2) local m=#A1 local n=#A2 local temp = {} local visited = {} for i = 1, m do temp[i] = A1[i] visited[i] = 0 end table.sort(temp) local ind = 0 for i = 1, n do local f = first(temp, 1, m, A2[i], m+1) if f then j = f while j <= m and temp[j] == A2[i] do -- 修复索引偏移:先自增再赋值,保证数组从1开始 ind = ind + 1 A1[ind] = temp[j] visited[j] = 1 j = j + 1 end end end for i = 1, m do if visited[i] == 0 then ind = ind + 1 A1[ind] = temp[i] end end -- 截断A1原有多余元素 for i = ind+1, #A1 do A1[i] = nil end end function printArray(arr) for i = 1, #arr do print(arr[i]) end end
字符串场景测试
使用你给出的两个表测试:
local OrderTbl = {'Hello', 'Question', 'Answer', 'Bye'} local UnsortedTbl = {'Question', 'Bye', 'Bye', 'Question', 'Hello', 'Something'} sortAccording(UnsortedTbl, OrderTbl) printArray(UnsortedTbl)
输出结果为:
Hello Question Question Bye Bye Something
更简洁的优化实现
原有移植的Java逻辑比较复杂,Lua原生支持自定义table.sort的比较函数,可以用更简单的方式实现需求,性能和可读性更好:
function sortByOrder(unsortedTbl, orderTbl) -- 构建优先级映射表,元素越靠前优先级值越小 local priority = {} for idx, val in ipairs(orderTbl) do priority[val] = idx end -- 自定义排序规则 table.sort(unsortedTbl, function(a, b) local pA = priority[a] local pB = priority[b] -- 两个元素都在优先级表中,按优先级排序 if pA and pB then return pA < pB end -- 只有a在优先级表中,a排在前面 if pA then return true end -- 只有b在优先级表中,b排在前面 if pB then return false end -- 都不在优先级表中,顺序随意 return a < b end) end
测试用例
local OrderTbl = {'Hello', 'Question', 'Answer', 'Bye'} local UnsortedTbl = {'Question', 'Bye', 'Bye', 'Question', 'Hello', 'Something'} sortByOrder(UnsortedTbl, OrderTbl) for _,v in ipairs(UnsortedTbl) do print(v) end
输出结果和上述修改后的代码一致。
内容的提问来源于stack exchange,提问作者alexkart82
相关产品推荐
相关产品推荐

