如何打印出非质数? PL/SQL [关闭]
Posted
技术标签:
【中文标题】如何打印出非质数? PL/SQL [关闭]【英文标题】:How to print out non-prime numbers? PL/SQL [closed] 【发布时间】:2013-04-23 14:13:21 【问题描述】:此代码用于打印 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;
【问题讨论】:
显然它不起作用。当i=1
时k in 2..i-1
解析为k in 2..0
。还有其他错误,但是这有点代码高尔夫的味道,所以它是题外话。
@APC:令人惊讶的是,这似乎确实有效。修复语法错误后,输出是正确的。 the5strace:请更正语法(仔细查看您的两个“for”行,您会发现不同之处)。然后记住;
不仅仅是装饰。有些地方需要它们。
@APC i=1
的情况是有效的,因为 plsql 要求第一个绑定低于第二个绑定才能进入循环。反转迭代顺序需要修饰符REVERSE
,如FOR k IN REVERSE lo..hi LOOP ...END LOOP
。
错误是它不打印1,它(按常识)不是质数,所以应该打印。
@FrankSchmitt - 我要对你对“共同理解”的使用提出质疑。我猜大多数非数学倾向的人仍然认为 1 是素数。我同意现代数学认为不再是这种情况了。
【参考方案1】:
喝了杯咖啡,所以这里是一个纯 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 中可用)。
【讨论】:
虚伪?既然可以在 SQL 中完成,为什么还要在 PL/SQL 中完成? @Colin'tHart - 我同意。但我称之为虚伪,因为我已经暗示这是 Code Golf 而不是一个正确的问题。 愚蠢的连贯性是小脑袋里的妖精。去伪善吧,哦伟大的思想家! :-)【参考方案2】:这是一个“它是如何工作的”的答案。
外部循环处理数字 1 - 30。
内部循环执行实际的非素数处理。只有在i = 4
(因为 1、2、3 是素数)之后它才会真正开始。对于大多数非质数,循环将在k <= 3
之后完成,并将打印出i
。
对于素数,它将遍历所有小于素数的数字。就像我们在 i = 23
上一样,内部循环将通过 2,3,4...22 并完成循环而不打印任何内容。
这是我不喜欢的部分。如果您将数字分解(特别是因为我们只处理 1 - 30),它们可以被 2 或 3 或另一个素数整除。这是愚蠢的部分。回到我们的i = 23
示例。我们将同时处理 mod(23, 3) 和 mod(23, 9) 和 mod(23, 18)。当然,如果 3 产生的余数比 9 和 18 也将产生余数(每个后续数字也将产生一个因数为 3 的数)。
【讨论】:
【参考方案3】:代码通过测试所有潜在候选者来工作,这意味着所有大于 1 且小于被审查数字的正整数。如果候选人将测试的数字除以没有余数,则该数字是复合数字并将被打印。跳过对帽子号的任何进一步测试。
【讨论】:
以上是关于如何打印出非质数? PL/SQL [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
pl/sql developer中写SQL时出现ORA-06550和PLS-00553
oracle PL/SQL里面, tnsnames.ora文件里面配置了之后, 在下拉列表框里面没有显示
如何使用EXECUTE关键字执行带参数的PL / SQL存储过程[关闭]
PL/SQL 如何修复进程标志 id=4 错误打印以及如何显示错误消息