[20250528]24点计算的SQL版本.txt

来源:这里教程网 时间:2026-03-03 22:02:13 作者:

[20250528]24点计算的SQL版本.txt --//有一张表 cards,id 是自增字段的数字主键,另外有4个字段 c1,c2,c3,c4 ,每个字段随机从 1~10 之间选择一个整数,要求选手 --//使用一条 SQL 给出 24 点的计算公式. --//单独写出一条sql语句有点难度,我先尝试使用sqlplus+ bash shell的方式实现看看,计算使用dc或者bc。 --//实际上sqlplus一般采用穷举方法计算,蛮力计算结果是否等于24,使用sqlplus,要根据运算符号计算2个数字的计算结果,每次运 --//算都是如此,处理难度集中在哪里,而且题目并没有除法时必须整除,另外运算除法时分母是0该如何处理。我简单一点,直接使用 --//sql语句写出运算的排列组合,然后交给XMLQUERY计算,我并没有建立表,先尝试直接带入4个数字计算。 $ cat 24dot.sql WITH FUNCTION js_exp (vc IN VARCHAR2)         RETURN NUMBER      AS         n   NUMBER;      BEGIN         SELECT TO_NUMBER (XMLQUERY (vc RETURNING CONTENT)) INTO n FROM DUAL;         RETURN n;      EXCEPTION         WHEN OTHERS         THEN            RETURN NULL;      END; x1         AS (SELECT 1 id, ' +' c FROM DUAL             UNION ALL             SELECT 8 id, ' -' FROM DUAL             UNION ALL             SELECT 1.2 id, ' *' FROM DUAL             UNION ALL             SELECT 16 id, ' /' FROM DUAL)     ,x2         AS (  SELECT decode(x1.c||x2.c||x3.c, ' - + *',-100, ' + + +',-90, ' * + +',-80, ' * - *',-70, ' + * -',-60, ' - * +',-50, ' + - *',-40, ' + * +',-30, x1.id + x2.id + x3.id) idop                     ,x1.c p1                     ,x2.c p2                     ,x3.c p3                 FROM x1, x1 x2, x1 x3             ORDER BY 1 )     ,y1         AS (SELECT 1 id, to_char(&&1,'999') n FROM DUAL             UNION ALL             SELECT 2 id, to_char(&&2,'999') FROM DUAL             UNION ALL             SELECT 3 id, to_char(&&3,'999') FROM DUAL             UNION ALL             SELECT 4 id, to_char(&&4,'999') FROM DUAL)     ,y2         AS (  SELECT DISTINCT x1.n n1                              ,x2.n n2                              ,x3.n n3                              ,x4.n n4                 FROM y1 x1                     ,y1 x2                     ,y1 x3                     ,y1 x4                WHERE     x1.id <> x2.id                      AND x1.id <> x3.id                      AND x1.id <> x4.id                      AND x2.id <> x3.id                      AND x2.id <> x4.id                      AND x3.id <> x4.id             ORDER BY 1 ,2 ,3 ,4) select txt,replace(dc1,'  ','') dc,replace(bc2,' ','') bc  from ( SELECT 'method 1' txt, '20k '||n1||n2||p1||n3||p2||n4||p3 dc1,'(('||n1||p1||n2||')'||p2||n3||')'||p3||n4 bc2 FROM y2, x2 union all SELECT 'method 2' txt, '20k '||n1||n2||p1||n3||n4||p2||p3 dc1,'('||n1||p1||n2||')'||p3||'('||n3||p2||n4||')' bc2 FROM y2, x2 union all SELECT 'method 3' txt, '20k '||n1||n2||n3||p1||p2||n4||p3 dc1,'('||n1||p2||'('||n2||p1||n3||'))'||p3||n4 bc2 FROM y2, x2 union all SELECT 'method 4' txt, '20k '||n1||n2||n3||n4||p1||p2||p3 dc1, n1||p3||'('||n2||p2||'('||n3||p1||n4||'))' bc2 FROM y2, x2 union all SELECT 'method 5' txt, '20k '||n1||n2||n3||p1||n4||p2||p3 dc1, n1||p3||'(('||n2||p1||n3||')'||p2||n4||')' bc2 FROM y2, x2 --) where TO_NUMBER(XMLQUERY(replace(bc2,'/','div') RETURNING CONTENT))=24 and rownum=1 --) where js_express(replace(bc2,'/','div') )=24 and rownum=1 --) where js_express(replace(bc2,'/','div') )=24 ) where js_exp(replace(bc2,'/','div') )=24 and rownum=1 --) where js_exp(replace(bc2,'/','div') )=24 ; / --//直接使用XMLQUERY有一个问题,遇到除法运算分母为0的情况会报错。 SCOTT@book01p> @ 24dot 1 2 3 4 TXT      DC                         BC -------- -------------------------- -------------------------- method 1 20k1 2 * 4 * 3 *           ((1*2)*4)*3 SCOTT@book01p> @ 24dot 1 5 5 5 WITH x1 * ERROR at line 1: ORA-01476: divisor is equal to zero. --//采用建立函数的方法绕过这个问题。 CREATE OR REPLACE FUNCTION js_express (vc IN VARCHAR2)    RETURN NUMBER AS    n   NUMBER; BEGIN    SELECT TO_NUMBER (XMLQUERY (vc RETURNING CONTENT)) INTO n FROM DUAL;    RETURN n; EXCEPTION    WHEN OTHERS    THEN       RETURN null; END; / SCOTT@book01p> @ 24dot 1 5 5 5 TXT      DC                         BC -------- -------------------------- -------------------------- method 3 20k5 1 5 / - 5 *           (5-(1/5))*5 --//12c支持sql自带函数,很容易改写实现,上面的代码已经采用自带函数的方式。 --//至于建立表cards再改进我就不做了。

相关推荐