|
|
solomon_007 发表于 2015-10-6 09:35 ![]()
#10
SQL> set timing on;
好吧给你发个章。你还真有耐心,我也写了递归版本但是等不了那么九。
改用二分法:
WITH d2 AS (
SELECT n1||n2 n
FROM (SELECT LEVEL n1 FROM DUAL CONNECT BY LEVEL<=5)
,(SELECT LEVEL n2 FROM DUAL CONNECT BY LEVEL<=5)
WHERE n1=n2 OR n1=1 OR n2=1
)
,d4 AS (
SELECT a.n||b.n n
FROM d2 a,d2 b
WHERE SUBSTR(a.n,2)=SUBSTR(b.n,1,1)
OR SUBSTR(a.n,2)=1
OR SUBSTR(b.n,1,1)=1
)
,d8 AS (
SELECT a.n||b.n n
FROM d4 a,d4 b
WHERE SUBSTR(a.n,4)=SUBSTR(b.n,1,1)
OR SUBSTR(a.n,4)=1
OR SUBSTR(b.n,1,1)=1
)
,d16 AS (
SELECT a.n||b.n n
FROM d8 a,d8 b
WHERE SUBSTR(a.n,8)=SUBSTR(b.n,1,1)
OR SUBSTR(a.n,8)=1
OR SUBSTR(b.n,1,1)=1
)
SELECT COUNT(*) FROM d16;
COUNT(*)
----------
64570081
Elapsed: 00:00:25.35
如果要求所有的数全部包含:
WITH d2 AS (
SELECT n1||n2 n
FROM (SELECT LEVEL n1 FROM DUAL CONNECT BY LEVEL<=5)
,(SELECT LEVEL n2 FROM DUAL CONNECT BY LEVEL<=5)
WHERE n1=n2 OR n1=1 OR n2=1
)
,d4 AS (
SELECT a.n||b.n n
FROM d2 a,d2 b
WHERE SUBSTR(a.n,2)=SUBSTR(b.n,1,1)
OR SUBSTR(a.n,2)='1'
OR SUBSTR(b.n,1,1)='1'
)
,d8 AS (
SELECT n
,INSTR(n,'1') p1
,INSTR(n,'2') p2
,INSTR(n,'3') p3
,INSTR(n,'4') p4
,INSTR(n,'5') p5
from (
SELECT CAST(a.n||b.n AS VARCHAR2(8)) n
FROM d4 a,d4 b
WHERE SUBSTR(a.n,4)=SUBSTR(b.n,1,1)
OR SUBSTR(a.n,4)='1'
OR SUBSTR(b.n,1,1)='1'
)
)
,d16 AS (
SELECT a.n||b.n n
FROM d8 a,d8 b
WHERE (SUBSTR(a.n,8)=SUBSTR(b.n,1,1)
OR SUBSTR(a.n,8)='1'
OR SUBSTR(b.n,1,1)='1'
)
AND a.p1+b.p1>0
AND a.p2+b.p2>0
AND a.p3+b.p3>0
AND a.p4+b.p4>0
AND a.p5+b.p5>0
)
SELECT COUNT(*) FROM d16;
COUNT(*)
----------
21310248
Elapsed: 00:00:29.19
|
|