如何使大型嵌套的 'for 循环' 更加紧凑?有什么解决办法吗?

我想知道是否有一种方法可以使大型嵌套的 'for 循环' 更加紧凑,从而减少代码量。

for a = 1, 10 do
  for b = 1, 10 do
    for c = 1, 10 do
      ...
        if a == 1 and b == 2 and c == 3 ... y == 4 and z == 5 then
          print("test")
        end
      ...
    end
  end
end
点赞
用户2858170
用户2858170

循环的任何形式在满足一定条件之前会重复执行它们的主体。

这已经是告诉计算机多次执行代码的最简单方法了。

因此,没有简化的必要。

在您的示例中,您可以简单地一次性执行print(“test”),因为您的条件很可能在10^24次迭代中仅满足一次。

2019-08-10 10:56:37
用户3574628
用户3574628

一种替代方法是将所有计数器变量存储在单个表中。然后,可以有一个循环调用一个函数,逐个调整计数器。

local N_COUNTERS = 8

-- 增加计数器。如果所有计数器都是10,则返回true。
local function uptick(counters)
  for i = #counters, 1, -1 do
    local n = counters[i]
    if n < 10 then
      counters[i] = n + 1
      return false
    end
    counters[i] = 1
  end
  return true
end

-- 查看所有计数器并返回布尔值。
local function doCheck(counters)
  for i, n in ipairs(counters) do
    if i ~= n then
      return false
    end
  end
  return true
end

local counters = {}
for i = 1, N_COUNTERS do
  counters[i] = 1
end

-- 循环调用计数器函数并检查计数器。
repeat
  if doCheck(counters) then
    print('test')
  end
until uptick(counters)

我将N_COUNTERS设置为8,因为这是在我的机器上运行的时间不会太长的最大值。我不知道是否有任何方法可以加快这个过程。

2019-08-10 15:50:49
用户2616735
用户2616735

你可以在 Lua 中编写自己的迭代器,这可以让你进行表达。手册 解释了它们是如何被调用的。

例如,这里有一个 grid 迭代器生成器,让你可以按字典顺序迭代一个“网格”:

-- Lua 5.1 的 "unpack" 在 Lua 5.2 中被重命名为 "table.unpack"
table.unpack = table.unpack or unpack

function iterator(t, i)
    local n = i + 1
    local r = {}
    local p = 1
    for k = #t, 1, -1 do
        p = p * t[k]

        -- 或者,在 Lua 5.3 中用 "c = i % t[k] // 1" 代替
        local c = i % t[k]
        r[k] = 1 + c

        -- 或者,在 Lua 5.3 中用 "i = i // t[k]" 代替
        i = (i - c) // t[k]
    end
    if n > p then
        return nil, table.unpack(r)
    end
    return n, table.unpack(r)
end

function grid(...)
    return iterator, {...}, 0
end

你可以像这样使用它:

for i, a, b, c in grid(10, 10, 10) do
    if a ^ 2 + b ^ 2 == c ^ 2 then
        print(string.format("%d^2 + %d^2 = %d^2", a, b, c))
    end
end

--> 3^2 + 4^2 = 5^2
--> 4^2 + 3^2 = 5^2
--> 6^2 + 8^2 = 10^2
--> 8^2 + 6^2 = 10^2

因为简单的 for i = 1, 10 do 循环由 Lua 自己提供,所以循环计数会比使用这样的迭代器快得多。然而,这种差异在每个迭代中要执行更多的工作时逐渐减小。如果每次迭代只做几行简单的代码,反复调用 iterator 的性能开销(也构建表!)将远远超过循环中实际完成的工作。但如果你只迭代几次,并且每次迭代都做很多工作,那么它的影响就不会太大。

2019-08-10 17:33:55