这是我的代码
SET SERVEROUTPUT ON;
DECLARE
ACOUNTER INTEGER;
IS_PRIME INTEGER;
BEGIN
IS_PRIME := 1;
FOR NUM IN 1000..2000 LOOP
FOR D IN 2..NUM-1 LOOP
IF MOD(NUM,D) = 0 THEN
IS_PRIME := 0;
END IF;
END LOOP;
END LOOP;
IF IS_PRIME = 1 THEN
ACOUNTER := ACOUNTER +1;
DBMS_OUTPUT.PUT_LINE('THE # OF PRIME NUMBERS BETWEEN 1000-2000 ARE: ' || ACOUNTER);
END;
我收到错误:
从第2行开始出错:命令中的错误 - 错误报告 - ORA-06550:行 18,第4栏:PLS-00103:遇到符号&#34 ;;"当期待一个 以下内容:
如果 06550. 00000 - "行%s,列%s:\ n%s" *原因:通常是PL / SQL编译错误。 *行动: END;
答案 0 :(得分:4)
此IF没有END IF
- IF IS_PRIME = 1 THEN
完整的END;
阻止没有BEGIN...END
。
错误告诉你你必须采取什么行动 -
行动:结束;
这通常意味着您必须将END关键字放在某处。
关于找到素数的算法的一些建议 -
检查素数时,您不必循环直到num-1。循环直到平方根(num)将正常工作。 Proof
当您找到不是素数的数字时,请退出循环。无需检查该号码的任何进一步除数。
编辑:你的逻辑错误会给你不正确的结果 -
在第一个循环中,将变量IS_PRIME重新初始化为1.
计数器增量应该在第一个循环中发生。
这是正确的程序 -
SET SERVEROUTPUT ON;
DECLARE
ACOUNTER INTEGER;
IS_PRIME INTEGER;
BEGIN
ACOUNTER := 0;
IS_PRIME := 1;
FOR NUM IN 1000 .. 2000
LOOP
IS_PRIME := 1;
FOR D IN 2 .. SQRT (num)
LOOP
IF MOD (NUM, D) = 0
THEN
IS_PRIME := 0;
EXIT;
END IF;
END LOOP;
IF IS_PRIME = 1
THEN
ACOUNTER := ACOUNTER + 1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE (
'THE # OF PRIME NUMBERS BETWEEN 1000-2000 ARE: ' || ACOUNTER);
END;
/
答案 1 :(得分:3)
你没有END IF
;如果报告错误的行号,则在显示的内容之后有END;
,所以最后几行是:
...
IF IS_PRIME = 1 THEN
ACOUNTER := ACOUNTER +1;
DBMS_OUTPUT.PUT_LINE('THE # OF PRIME NUMBERS BETWEEN 1000-2000 ARE: ' || ACOUNTER);
END;
/
当编译器看到END;
期望前面的IF
被关闭时,它会在看到;
时抛出异常。只需在主要检查后添加END IF
:
...
IF IS_PRIME = 1 THEN
ACOUNTER := ACOUNTER +1;
END IF;
DBMS_OUTPUT.PUT_LINE('THE # OF PRIME NUMBERS BETWEEN 1000-2000 ARE: ' || ACOUNTER);
END;
/
一致的缩进使这种更明显,更容易追踪。
你也在错误的地方设置和检查你的标志 - 两者都应该在第一个循环中 - 你必须在开始之前初始化你的计数器,因为它将默认为null:
DECLARE
ACOUNTER INTEGER := 0;
IS_PRIME INTEGER;
BEGIN
FOR NUM IN 1000..2000 LOOP
IS_PRIME := 1;
FOR D IN 2..NUM-1 LOOP
IF MOD(NUM,D) = 0 THEN
IS_PRIME := 0;
END IF;
END LOOP;
IF IS_PRIME = 1 THEN
ACOUNTER := ACOUNTER +1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('THE # OF PRIME NUMBERS BETWEEN 1000-2000 ARE: ' || ACOUNTER);
END;
/
anonymous block completed
THE # OF PRIME NUMBERS BETWEEN 1000-2000 ARE: 135
请参阅@ ruudvan关于算法的评论;该版本获得相同的答案135,但效率更高(在我的系统上的十分之一时间;使用这种更简单的方法,大约0.06秒对0.60)。
答案 2 :(得分:1)
Alex Poole解决了代码的实际问题。但是,与许多问题一样,如果您要在数据库中解决这个问题,那么使用SQL可能会更好。本着这种精神,这个问题的SQL解决方案如下。
WITH pc AS
(SELECT *
FROM (SELECT LEVEL AS numbers
FROM DUAL
CONNECT BY LEVEL <= 2000)
WHERE (numbers = 2 OR MOD (numbers, 2) <> 0) AND numbers <> 1)
SELECT *
FROM (SELECT numbers FROM pc
MINUS
SELECT pc1.numbers
FROM pc pc1
JOIN pc pc2
ON pc2.numbers <= CEIL (SQRT (pc1.numbers))
AND MOD (pc1.numbers, pc2.numbers) = 0)
WHERE numbers BETWEEN 1000 AND 2000
connect by
生成1到2000之间的所有数字。使用公认的规则,我们可以消除高于2的所有偶数,并且只测试每个数字的模数,以获得低于数字平方根的值。
从技术上讲,这个解决方案生成2到2000之间的每个素数,然后过滤掉2000以下的所有素数。由于在一秒钟内产生完整的结果,额外的工作是无关紧要的。