如何找到(例如)此迷宫中的最短路径(在明确的SQL上,不使用PL / SQL函数):
起点:'s',终点:'e'
'00 000 e000000'
' 0 '
'0000 000 0 00000 '
' 0 0 0 '
's0 000 000 00000 '
' 0 '
结果,应该有这样的东西
'00 000 e000000'
' 0- '
'0000 000 0-00000 '
'---0 0 -0 '
's0-000 000-00000 '
' 0--------- '
我不是在等待SQL代码中的现成解决方案,但我不知道它是如何在SQL中解决的。谁能知道任何算法?目标数据库Oracle。
答案 0 :(得分:1)
既然你在征求意见:
答案 1 :(得分:1)
有两种方法
<强>更新。快速演示第一种方法。
column str format a30
with t(y, str) as
( select 1, '00 000 e000000' from dual
union all select 2, ' 0 ' from dual
union all select 3, '0000 000 0 00000 ' from dual
union all select 4, ' 0 0 0 ' from dual
union all select 5, 's0 000 000 00000 ' from dual
union all select 6, ' 0 ' from dual)
, matrix as
(select x, y, str, substr(str, x, 1) z, rownum id
from t
cross join (select rownum x from dual connect by level <= 17))
, rec(x,y,z,id_list) as
(select x, y, z, cast(id as varchar2(4000)) from matrix where z = 's'
union all
select m.x, m.y, m.z, r.id_list || '|' || m.id
from matrix m
join rec r on (r.x + 1 = m.x and r.y = m.y
or r.x - 1 = m.x and r.y = m.y
or r.x = m.x and r.y + 1 = m.y
or r.x = m.x and r.y - 1 = m.y)
and instr('|' || r.id_list || '|', '|' || m.id || '|') = 0
and m.z != '0'
and r.z = any ('s', ' ')
)
, route as
(select regexp_substr(x, '\d+', 1, rownum) mark
from
(select max(id_list) keep
(dense_rank first order by regexp_count(id_list,'|')) x
from rec
where z = 'e')
connect by level <= regexp_count(x,'|'))
select y, listagg(decode(z, ' ', nvl2(mark, '=', z), z))
within group (order by x) str
from matrix
left join route on id = mark
group by y
order by y;
Y STR
---------- ------------------------------
1 00 000 e000000
2 0=
3 0000 000 0=00000
4 ===0 0 =0
5 s0=000 000=00000
6 0=========
6 rows selected.
模型解决方案效率更高,但SQL并不是解决此特定任务的最佳方法。