现在有一个需求: 针对一个答题统计, 需要统计近5次的错误次数.

思路是, 使用数表去储存这5次错误次数, 然后统计数表

现在有一个5个元素的数表 error_last_5_times = {1, 0, 1, 0 ,1} 其中1表示正确, 0表示错误

这里有两种统计方法:

-- 方法1: 使用迭代数表来统计
error_last_5_times = {1, 0, 1, 0 ,1}
total1 = function (error_last_5_times)
  local wrong_times = 0
  for i = 1, 5 do
    if error_last_5_times[i] == 0 then
      wrong_times = wrong_times + 1
    end
  end
  return wrong_times
end
-- 方法2: 使用字符串统计
error_last_5_times = {1, 0, 1, 0 ,1}
total2 = function (error_last_5_times)
  local _, wrong_times
  -- 将数表转化为字符串, 统计替换字符串中"0"的次数
  _, wrong_times = table.concat(error_last_5_times, ""):gsub("0", "")
  return wrong_times
end

通常而言, total1 函数会更快一些, 但是可读性上不是很好.

total2 函数因为使用到了两个内置函数( table.concatstring.gsub )去处理, 可读性上会更高, 但是效率会稍微差上一些, 这一点点出来之后稍微回看一下代码就可以比较清楚的理解了.

还有一个新的需求: 因为是一个答题模拟, 所以不断地有新的数据传入, 需要将新数据答题的正确或者错误, 写入 error_last_5_times 这个表中, 但是需要统计的还是近5次的错误次数.

也就是, 需要一个添加新数据的函数.

一样的, 我们看两个函数:

-- 方法1: 使用循环缓存结构去添加新数据
-- 在`error_last_5_times`表中添加一个键`index`, 用来缓存循环数
error_last_5_times = {1, 0, 1, 0 ,1 , index = 0}
add1 = function (error_last_5_times, value)
  -- 使用余数进行限制循环
  error_last_5_times.index = (error_last_5_times.index % 5) + 1
  error_last_5_times[error_last_5_times.index] = value
  return error_last_5_times
end

在上面这个方法中, 使用了一个循环缓存结构去添加新数据, 即 error_last_5_times.index 是一个从1~5逐步循环的数, 当超过6的数出现时, 会回滚到前面的索引并覆盖原来的数据, 这使得添加新数据并不需要很高的运算.

-- 方法2: 使用内置表操作函数去添加新数据
error_last_5_times = {1, 0, 1, 0 ,1}
add2 = function (error_last_5_times, value)
  table.insert(error_last_5_times, 1, value)
  table.remove(error_last_5_times)
  return error_last_5_times
end

在这一个方法中, 每次添加新数据, 会使用 table.inseterror_last_5_times 的第一个元素添加新的正确率数据, 并使用 table.remove 删除最后一个数据, 由于Lua中移动表的效率较低, 所以很明显, 这也是一个增加可读性以减少程序效率的方法.

发表回复