|
#268 用递归,花了差不多一小时。没有考虑野花说的临界点的误差情况。顺便把36楼的代码精简了一下。
DECLARE
TYPE t_prime IS RECORD (
pn NUMBER,lg NUMBER
);
TYPE t_primes IS TABLE OF t_prime;
lv_primes t_primes := t_primes();
lv_limit NUMBER := 16;
lv_cnt NUMBER;
FUNCTION f_cnt(
p_level IN NUMBER
,p_start IN NUMBER
,p_sum IN NUMBER
) RETURN NUMBER
AS
lv_cnt_rest NUMBER:=0;
lv_sum NUMBER;
BEGIN
IF p_start>lv_primes.COUNT OR p_sum<=0 THEN
RETURN 0;
END IF;
FOR i IN p_start..lv_primes.COUNT LOOP
lv_sum := lv_primes(i).lg;
IF lv_sum>p_sum THEN
EXIT;
END IF;
WHILE lv_sum<=p_sum LOOP
lv_cnt_rest := lv_cnt_rest+ (CASE WHEN p_level>=4 THEN 1 ELSE 0 END)+f_cnt(p_level+1,i+1,p_sum-lv_sum);
lv_sum := lv_sum+lv_primes(i).lg;
END LOOP;
END LOOP;
RETURN lv_cnt_rest;
END f_cnt;
BEGIN
WITH
t as(SELECT 2*ROWNUM+1 rn FROM DUAL CONNECT BY 2*ROWNUM+1 <= 100
)
SELECT pn,LOG(10,pn)
BULK COLLECT INTO lv_primes
FROM (
SELECT rn pn from t
MINUS
SELECT t1.rn * t2.rn
FROM t t1, t t2
WHERE t1.rn <= t2.rn
AND t1.rn <=SQRT(100)
AND t1.rn * t2.rn <100
UNION ALL SELECT 2 FROM DUAL
)
ORDER BY pn;
lv_cnt := f_cnt(1,1,lv_limit);
DBMS_OUTPUT.PUT_LINE('count='||lv_cnt);
END;
/
count=2344465914
PL/SQL procedure successfully completed.
Elapsed: 00:58:35.74
|
|