如何打印非素数? PL / SQL

时间:2013-04-23 14:13:22

标签: database oracle plsql

此代码用于打印1到30之间的非素数。它是如何工作的以及错误在哪里。

BEGIN  
    <<outer>>
    FOR i in 1..30
        <<inner>> 
        for k in 2..i-1 loop 
            if (mod(i, k) = 0) THEN 
                DBMS_OUTPUT.PUT_LINE(i);
                exit inner when (mod(i, k)= 0);
            end if;
        end loop inner
    end loop outer 
end;

3 个答案:

答案 0 :(得分:5)

喝咖啡休息时间,所以这里是一个纯粹的SQL实现。

with data as ( select level as n# from dual 
               connect by level <= 30 )
select distinct d1.n#
from data d1 cross join data d2
where d1.n# > d2.n#
and d2.n# != 1
and mod(d1.n#, d2.n#) = 0
order by d1.n#

虚伪?哎呀!


此解决方案具有相同的低效率which @TYH points out in the PL/SQL solution。这就是它需要distinct的原因。可能这可以通过递归CTE进行优化(仅适用于11gR2)。

答案 1 :(得分:1)

这是一个“它如何运作”的答案。

外部循环处理数字1 - 30。

内循环执行实际的非素数处理。它真的只在i = 4之后才开始(因为1,2,3是素数)。对于大多数非素数,循环将在k <= 3之后完成,并且将打印出i。 对于素数,它将循环遍历所有小于素数的数字。就像我们在i = 23上一样,内循环将通过2,3,4 ... 22并完成循环而不打印任何东西。

这是我不喜欢的部分。如果你将数字分解(特别是因为我们只处理1 - 30),它们可以被2或3或另一个Prime数整除。这是愚蠢的部分。回到我们的i = 23示例。我们将处理mod(23,3)和mod(23,9)以及mod(23,18)。当然,如果3产生的余数超过9,那么18也将产生余数(每个后续数字的因子为3)。

答案 2 :(得分:0)

该代码通过测试所有潜在的候选者来工作,这意味着所有正整数大于1且更少受到审查的数量。如果候选人在没有余数的情况下划分测试的数字,则该数字是复合的并且将被打印。对帽子编号的任何进一步测试都会被跳过。