生成所有唯一的k子序列

时间:2019-10-22 17:25:52

标签: python itertools formal-languages subsequence

我正在尝试编写一个Python函数(至少在最初是这样),以生成某个长度为k(其中k> 0)的所有子序列。由于我只需要唯一的子序列,因此我会将子序列和部分子序列存储在set中。以下是我从同事那里改编而成的,是我能想到的最好的。似乎……太复杂了……就像我应该能够滥用itertools或递归来做我想做的事情。谁能做得更好?

from typing import Set, Tuple


def subsequences(string: str, k: int) -> Set[Tuple[str, ...]]:
    if len(string) < k:
        return set()
    start = tuple(string[:k])
    result = {start}
    prev_state = [start]
    curr_state = set()
    for s in string[k:]:
        for p in prev_state:
            for i in range(k):
                new = p[:i] + p[i + 1 :] + (s,)
                curr_state.add(new)
        result.update(curr_state)
        prev_state = list(curr_state)
        curr_state.clear()
    return result

(就上下文而言,我对归纳k-strictly piecewise languages(一种可正常学习的常规语言的子类,很感兴趣,并且语法可以由所有合法的k子序列表征)。

最终我也正在考虑在C ++中做到这一点,其中std::make_tuple不如Python tuple强大。)

1 个答案:

答案 0 :(得分:2)

您希望从r个项目中获得一组n组合(不替换,<= (n choose r)

给出

import itertools as it

import more_itertools as mit

代码

选项1 -itertools.combinations

set(it.combinations("foo", 2))
# {('f', 'o'), ('o', 'o')}

set(it.combinations("foobar", 3))
# {('b', 'a', 'r'),
#  ('f', 'a', 'r'),
#  ('f', 'b', 'a'),
#  ('f', 'b', 'r'),
#  ('f', 'o', 'a'),
#  ('f', 'o', 'b'),
#  ('f', 'o', 'o'),
#  ('f', 'o', 'r'),
#  ('o', 'a', 'r'),
#  ('o', 'b', 'a'),
#  ('o', 'b', 'r'),
#  ('o', 'o', 'a'),
#  ('o', 'o', 'b'),
#  ('o', 'o', 'r')}

选项2 -more_itertools.distinct_combinations

list(mit.distinct_combinations("foo", 2))
# [('f', 'o'), ('o', 'o')]

list(mit.distinct_combinations("foobar", 3))
# [('f', 'o', 'o'),
#  ('f', 'o', 'b'),
#  ('f', 'o', 'a'),
#  ('f', 'o', 'r'),
#  ('f', 'b', 'a'),
#  ('f', 'b', 'r'),
#  ('f', 'a', 'r'),
#  ('o', 'o', 'b'),
#  ('o', 'o', 'a'),
#  ('o', 'o', 'r'),
#  ('o', 'b', 'a'),
#  ('o', 'b', 'r'),
#  ('o', 'a', 'r'),
#  ('b', 'a', 'r')]

两个选项都产生相同的(无序)输出。但是:

  • 选项1接受所有组合(包括重复项)的集合
  • 选项2不会计算重复的中间体

通过more_itertools安装> pip install more_itertools

另请参见以书面Python编写的itertools.combinations中的rough implementation