【问题标题】:Partitioning a (string or integer) into n-elements of min (length or value) of 2将一个(字符串或整数)划分为最小(长度或值)为 2 的 n 个元素
【发布时间】:2016-07-22 17:27:20
【问题描述】:

我有一个包含 ~120'000 个不同长度(从 4 到 27)的字符串的列表,我想检查这些字符串是否由字典中存在的子字符串组成,并且这些子字符串可以是各种长度,最少 2 个字符。

例如,一个 9 个字符长的字符串将被分成最少 2 个子字符串。当然我需要所有可能的组合

astring = '123456789'
# possible divisions
2 sub-strings = [['12','3456789'],['1234567','89'],['123','456789'],...]
3 sub-strings = [['12345', '67','89'],['1234','567','89']...]
4 sub-strings = [['12','34','56','789'],['12','34','567','89']...]

我找到了code below at this address,在根据要求拒绝结果后,我得到了我需要的东西,但我不确定它是不是太慢了。在 18 个字符长的字符串中,处理一个字符串需要 2 秒(整个列表需要几个小时)。 如果是 18 个字符长的字符串,我可以从 131072 个中得到 1596 个好的切片,所以 98% 是没用的。 有更快的方法吗?

from itertools import chain, combinations

def partition(iterable, chain=chain, map=map):
    s = iterable if hasattr(iterable, '__getslice__') else tuple(iterable)
    n = len(s)
    first, middle, last = [0], range(1, n), [n]
    getslice = s.__getslice__
    return [map(getslice, chain(first, div), chain(div, last))
            for i in range(n) for div in combinations(middle, i)]
some_string = '12345678'

for xyz in xrange(100):
    for x in partition(some_string):
        if (any(len(astring) == 1 for astring in x)):
            continue
        if len(x) == 1:
            continue
        # otherwise do something here

指定回答 eyquem 评论:

我有一本日语单词词典(日语不使用空格),并且很多长度为 4 个字符或更长的单词是由较短单词组成的复合词。我想过滤掉那些可以拆分成较短单词的单词。稍后我可以查看列表并确保单词切片具有语义意义。

这种方法是一种残酷的力量,我认为它会更简单,我可以使用它来代替更合乎逻辑但更复杂且递归有限的 for 循环。 从左边开始,找到最长的单词...

问候 巴特

【问题讨论】:

  • @tehjoker Code Review 只审查作者自己的代码。
  • 在这120'000个字符串中,有多少个子字符串被关注和被搜索?为什么这些子字符串会出现在字典中?它们是字典中的键或值,还是集合中的字典值?
  • Python 2.7.11 文档:operator.__getslice__(a, b, c) :将 a 的切片从索引 b 返回到索引 c-1。 自 2.6 版起已弃用:此函数在 Python 3.x 中已删除。将 getitem() 与切片索引一起使用。
  • 感谢 eyquem。与此同时,我编写了一个递归有限的代码,它可以在 0.7 秒内快速运行 70'000 个条目,但它需要 80 行,所以绝对不优雅。使用对整数进行分区但跳过包含 1 的结果并从最少整数到最多生成结果的生成器,getslice(a, b, c) 会好得多。我不确定是否应该在此处发布代码,因为它不能完全回答问题?

标签: python string slice


【解决方案1】:

我不确定这是否有帮助,但您可以尝试实施修改后的 radix tree。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 2020-03-13
    • 2010-11-03
    • 2011-12-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多