很早以前就想用PLSQL写一个算24点的程序了,后来想了一下没有研究下去,最近上ITPUB的时候正好大家都在讨论,在大牛的基础上修改了一下,基本上思想和算法都是没有变的,就是学习了一下。还有两个大问题没有处理好,一是只用了枚举法,用PLSQL应该可以换个更好的递归算法的;二是没有滤重;反正最后的结果只是最简单的得到答案而已。
具体的可以参见:
http://www.itpub.net/viewthread.php?tid=1061129&extra=page%3D1%26amp%3Bfilter%3Ddigest&page=1
http://www.itpub.net/viewthread.php?tid=1077244&extra=&page=1
create or replace function f_op (p_n1 number , p_op varchar2 , p_n2 number ) return number
as
begin
return case when p_op = '+' then p_n1 + p_n2
when p_op = '-' then p_n1 - p_n2
when p_op = '*' then p_n1 * p_n2
when p_op = '/' and p_n2<> 0 then p_n1 / p_n2
else null
end ;
end f_op;
/
create or replace procedure pro_24(p1 number , p2 number , p3 number , p4 number ) as
r_result number default 0 ;
begin
for r in (
with t_num as
( select 1 id ,p1 as n from dual
union
select 2 id ,p2 as n from dual
union
select 3 id ,p3 as n from dual
union
select 4 id ,p4 as n from dual),
t_op as
( select '+' as o from dual
union
select '-' as o from dual
union
select '*' as o from dual
union
select '/' as o from dual)
select distinct
a.n as a,
o1.o as o1,
b.n as b,
o2.o as o2,
c.n as c,
o3.o as o3,
d.n as d
from t_num a, t_num b, t_num c, t_num d,
t_op o1, t_op o2, t_op o3
where a.id not in (b.id, c.id, d.id)
and b.id not in (c.id, d.id)
and c.id <> d.id) loop
r_result := f_op(f_op(f_op(r.a,r.o1,r.b),r.o2,r.c),r.o3,r.d);
if r_result between 23.9 and 24.1 then
dbms_output.put_line( '((' ||r.a||r.o1||r.b|| ')' ||r.o2||r.c|| ')' ||r.o3||r.d);
end if ; --((a b) c) d
r_result := f_op(f_op(r.a,r.o1,f_op(r.b,r.o2,r.c)),r.o3,r.d);
if r_result between 23.9 and 24.1 then
dbms_output.put_line( '(' ||r.a||r.o1|| '(' ||r.b||r.o2||r.c|| '))' ||r.o3||r.d);
end if ; --(a (b c)) d
r_result := f_op(f_op(r.a,r.o1,r.b),r.o2,f_op(r.c,r.o3,r.d));
if r_result between 23.9 and 24.1 then
dbms_output.put_line( '(' ||r.a||r.o1||r.b|| ')' ||r.o2|| '(' ||r.c||r.o3||r.d|| ')' );
end if ; --(a b) (c d)
r_result := f_op(r.a,r.o1,f_op(f_op(r.b,r.o2,r.c),r.o3,r.d));
if r_result between 23.9 and 24.1 then
dbms_output.put_line(r.a||r.o1|| '((' ||r.b||r.o2||r.c|| ')' ||r.o3||r.d|| ')' );
end if ; --a ((b c) d)
r_result := f_op(r.a,r.o1,f_op(r.b,r.o2,f_op(r.c,r.o3,r.d)));
if r_result between 23.9 and 24.1 then
dbms_output.put_line(r.a||r.o1|| '(' ||r.b||r.o2|| '(' ||r.c||r.o3||r.d|| '))' );
end if ; --a (b (c d))
end loop ;
end ;
/
exec pro_24( 3 , 3 , 8 , 8 );
-The End-