通过算法有效地“完成”一组

时间:2018-12-17 02:53:16

标签: python algorithm performance set big-o

我有这个玩具小问题困扰着我。我认为这等同于许多更严重的等效问题。不,这不是家庭作业或面试问题……尽管如果我觉得自己知道一个可证明的最佳解决方案,也许可以在某个时候用它来面试人们。

我学会了 supervocalic (形容词,一个形容一个单词或短语的五个元音(A,E,I,O和U)恰好一次)。例如“问号”,“灵巧”,当然还有“超声”。

我编写了一个小型Python程序来识别含糊不清的单词。这很容易,其核心是:

matches = {}
for w in words:
    pat = tuple(w.count(v) for v in vowels)
    if pat in matches:
        matches[pat].add(w)
    else:
        matches[pat] = {w}

words仅仅来自于我拥有的庞大单词列表(SOWPODS Scrabble词典,大约有270k个单词。我可以简单地用matches[(1,1,1,1,1)]来识别高声单词……也就是说,具有确切含义的单词是什么FWIW,vowels在这里在技术上是可配置的,因此我的小脚本可以对字符的任何子集(和任何单词列表)进行等效的操作。

我的问题是我想找到所有过分的 ngrams 。单词是1克。什么2克,3克等也构成了超然的短语。事实证明,我有175个单词,没有AEIOU;因此从技术上讲,这些功能集的每个元素都可以附加到每个不包含它们的ngram中。很多。

但是,如果忽略每个“填充的”超表达短语的2 ^ 175个额外变体,那么如何合并计数元组。在元音计数方面有很多相等的单词,因此当然有很多组合,例如:

pat: (1, 0, 1, 0, 0); numwords: 5499
pat: (0, 1, 0, 1, 1); numwords: 2703

因此,从第一个列出的组中选取任何一个,从第二个列出的组中选取其他任何一个,均符合资格。那就是14,863,797 2克。实际上,因为任何一个顺序都可以,所以两倍多。

让我们还假设我抛弃了所有带有不止一个元素的模式,因为这些单词本身太“丰富”,所以这些单词不能包含在任何过分的短语中。

我可以目睹(1, 0, 1, 0, 0)(0, 1, 0, 1, 1)是互补的模式,它们将一起“填充”元音空间(或问题的一般版本中的元素的任何空间)。对于任意长度的任意元组,我如何找到所有N个大小的元组集合,这些集合将合并为“填充的元组”(而不是过度填充的元组)?

从本质上讲,尽管有所准备,但这是我要找到的这些N个互补的元组集合的问题,这是对任意元组长度(不仅是长度5)的最有效方式,即使我更喜欢Python和我的简短代码段是,这个问题几乎适用于任何编程语言。

0 个答案:

没有答案