如何在PostgreSQL中创建一个字/字符串的所有可能字谜列表

问题描述 投票:1回答:2

如何在PostgreSQL中创建一个字/字符串的所有可能字谜的列表。

例如,如果字符串是“行为”,那么所希望的输出应为:

行为,ATC,CTA,猫,TAC,TCA

我有一个表“tbl_words”其中包含的单词万元。

然后,我要检查/搜索唯一有效的话在我的数据库表从这个字谜名单。

从上面字谜的列表,例如有效的词是:行为,猫。

有没有办法做到这一点?

更新1:

我需要这样的输出:(所有置换给定字)

enter image description here

任何想法 ??

sql postgresql anagram
2个回答
2
投票

查询生成设置3个元素的所有排列:

with recursive numbers as (
    select generate_series(1, 3) as i
),
rec as (
    select i, array[i] as p
    from numbers
union all
    select n.i, p || n.i
    from numbers n
    join rec on cardinality(p) < 3 and not n.i = any(p)
)
select p as permutation
from rec
where cardinality(p) = 3
order by 1

 permutation 
-------------
 {1,2,3}
 {1,3,2}
 {2,1,3}
 {2,3,1}
 {3,1,2}
 {3,2,1}
(6 rows)

修改最终的查询,生成一个给定的单词的字母排列的:

with recursive numbers as (
    select generate_series(1, 3) as i
),
rec as (
    select i, array[i] as p
    from numbers
union all
    select n.i, p || n.i
    from numbers n
    join rec on cardinality(p) < 3 and not n.i = any(p)
)
select a[p[1]] || a[p[2]] || a[p[3]] as result
from rec
cross join regexp_split_to_array('act', '') as a
where cardinality(p) = 3
order by 1

 result 
--------
 act
 atc
 cat
 cta
 tac
 tca
(6 rows)    

1
投票

这里是一个解决方案:

with recursive params as (
      select *
      from (values ('cata')) v(str)
     ),
     nums as (
      select str, 1 as n
      from params
      union all
      select str, 1 + n
      from nums
      where n < length(str)
     ),
     pos as (
      select str, array[n] as poses, array_remove(array_agg(n) over (partition by str), n) as rests, 1 as lev
      from nums
      union all
      select pos.str, array_append(pos.poses, nums.n), array_remove(rests, nums.n), lev + 1
      from pos join
           nums
           on pos.str = nums.str and array_position(pos.rests, nums.n) > 0
      where cardinality(rests) > 0
     )
select distinct pos.str , string_agg(substr(pos.str, thepos, 1), '')
from pos cross join lateral
     unnest(pos.poses) thepos
where cardinality(rests) = 0 
group by pos.str, pos.poses;

这是相当棘手,特别是当有反复字母的字符串中。这里采用的方法生成的数字从1到n,其中n是串的长度的所有排列。然后使用这些为指标从原来的字符串中提取的字符。

这些谁热衷会发现,这里使用select distinctgroup by。这似乎是,以避免产生重复的字符串最简单的方法。

© www.soinside.com 2019 - 2024. All rights reserved.