Lua非1起始序列的内存占用及起始索引查询问题
Lua表的内存存储与非1起始连续索引的查找
问题1:表s和t的内存存储方式
Lua的表内部分为数组部分(存储从1开始的连续整数索引键值对,即官方定义的「序列」)和哈希部分(存储非序列类的键值对,包括非1起始、不连续的整数键,或非整数键)。
对于表
s:s[1]、s[2]是从1开始的连续整数索引,属于序列范畴,会被存在数组部分,占用2个words;s[0]是非1起始的整数键,不属于序列,会被存在哈希部分,占用1个word;- 总共占用3个words,不会额外消耗更多内存。
对于表
t:- 所有键(4、5、6)都不是从1开始的连续整数,因此全部键值对都存放在哈希部分,占用3个words,不会使用数组部分存储。
问题2:查找非1起始的连续整数索引序列的起始位置
Lua的数组部分(序列)固定从1开始,ipairs也只会遍历这部分内容。如果表中存在非1起始的连续整数索引(比如s的0、1、2,t的4、5、6),这些属于哈希部分,无法通过ipairs或#运算符直接获取,需要自行实现遍历逻辑:
实现思路
- 筛选并收集表中所有整数类型的键;
- 对整数键进行排序;
- 遍历排序后的键,找到最长的连续整数序列的起始索引(若需获取所有连续序列,可修改逻辑返回多个结果)。
示例代码
function findLongestContinuousStart(t) local intKeys = {} -- 筛选并收集所有整数键 for k in pairs(t) do if type(k) == "number" and math.floor(k) == k then table.insert(intKeys, k) end end if #intKeys == 0 then return nil end table.sort(intKeys) local bestStart = intKeys[1] local bestLength = 1 local currentStart = bestStart local currentLength = 1 for i = 2, #intKeys do if intKeys[i] == intKeys[i-1] + 1 then currentLength = currentLength + 1 if currentLength > bestLength then bestLength = currentLength bestStart = currentStart end else currentStart = intKeys[i] currentLength = 1 end end return bestStart, bestLength end -- 测试示例 local s = {[0]=4, [1]=5, [2]=6} local startS, lenS = findLongestContinuousStart(s) print("表s的最长连续序列起始索引:" .. startS .. ",长度:" .. lenS) -- 输出 0,3 local t = {[4]=4, [5]=5, [6]=6} local startT, lenT = findLongestContinuousStart(t) print("表t的最长连续序列起始索引:" .. startT .. ",长度:" .. lenT) -- 输出4,3
如果仅需验证某个候选起始索引的连续序列,也可以直接从该索引开始逐个检查t[k]是否存在,直到出现nil为止。
内容的提问来源于stack exchange,提问作者Sebastien Diot
相关产品推荐
相关产品推荐

