“for”和/或“if,then”语句的问题

时间:2011-07-25 04:57:00

标签: loops for-loop lua

这是一个看似简单的函数来生成素数。但是,它没有按预期工作。我已经浏览了在线指南,但我似乎无法理解它。非常感谢您的帮助。

primes = function(limit)
local t = {2}
for i = 3, math.sqrt(limit) do
    for k, v in ipairs(t) do
        if i % v == 0 then -- check if "i" is evenly divisible by each table element
            break
        else table.insert(t, i) -- if it is not, it is a prime number
            break
        end
     end
 end
 return t
 end

当我这样做时:

 for k, v in ipairs(primes(15)) do print (k, v) end

我明白了:

1   2
2   3
3   5
4   7
5   9
6   11
7   13
8   15

9和15不是素数,看起来第二个“for”循环不会越过表(2)中的第一个元素。在这种情况下使用“for”循环的正确方法是什么?

谢谢,文斯

编辑:将传入的参数限制为其建议的平方根。

2 个答案:

答案 0 :(得分:3)

您插入太快,必须在插入之前完成for循环。这是一种方式:

primes = function(limit)
local t = {2}
local is_prime, i_rt
for i = 3, limit do
    is_prime=true
    i_rt=math.sqrt(i)
    for k, v in ipairs(t) do
        if i % v == 0 then -- evenly divisible, not prime
            is_prime=false
            break
        end
        if v > i_rt then -- break once you exceed square root of i for efficiency
          break
        end
     end
     if is_prime then
         table.insert(t, i) -- insert if it is a prime
     end
 end
 return t
 end

一个例子:

> for k, v in ipairs(primes(50)) do print (k, v) end
1   2
2   3
3   5
4   7
5   11
6   13
7   17
8   19
9   23
10  29
11  31
12  37
13  41
14  43
15  47

答案 1 :(得分:1)

我认为您只需要翻转for循环的顺序。实际上,你是针对每个数字测试3,然后针对每个数字测试4,然后针对每个数字测试5,依此类推。如果你切换两个“for”语句,你将比较3,4,5 ...与第一个数字3,4,5 ...比较第二个数字3,4,5 ...反对第三个数字等等。

修改

实际上,你还需要做更多的事情。你必须确保没有3,4,5 ...除去数字,然后在内部for循环之后插入数字,如果没有进入。此外,你应该限制你的内循环停止在sqrt( v),因为如果sqrt(v)下没有任何东西除v,那么sqrt(v)之外的任何东西都不会(除了v)。

修改

实际上,我认为我误解了你的代码,你应该忽略我说的话。将内部循环限制为sqrt,但除此之外,请使用BMitch所说的内容。