【问题标题】:Generate list of word permutations from a set of words [duplicate]从一组单词生成单词排列列表[重复]
【发布时间】:2016-08-09 06:41:25
【问题描述】:

我有 13 个不同的单词。 我需要得到这些词的所有组合这样的排列:

word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12 word13

但组合只能是 12 个字长。

我已经在 python 中有一个脚本来执行此操作:

import time
start = time.time()
items = ['word1', 'word2', 'word3', 'word4', 'word5', 'word6', 'word7', 'word8', 'word9', 'word10, 'word11', 'word12', 'word13']
from itertools import permutations
for p in permutations(items, 12):
        print(p)
print 'It took', time.time()-start, 'seconds.'

但是太慢了,组合只有4个字的时候需要24秒。

javascript tool 只需要 1 秒就可以输入多达 9 个不同的单词;但是当尝试 10 个不同的单词时,浏览器崩溃了。

有没有一种快速有效的方法来做到这一点?也许是awk

编辑:

这与Generating permutations using bash 不是同一个问题,因为这个问题有 13 个单独的单词,而另一个线程中的答案不适用于单词。

亲切的问候。

【问题讨论】:

  • 对于排列和组合的术语经常存在混淆,所以让我们澄清一下您要查找的内容。假设只有三个单词:ABC,并且您正在寻找 2 个单词长的组合列表。你期待哪个列表? (1) AB,AC,BA,BC,CA,CB (2) AB,AC,BC(即订单无关紧要) (3) AA,AB,AC,BA,BB,BC,CA,CB,CC (4) AA,AB,AC,BB,BC,CC
  • 会在您的示例中使用列表 (1):
  • 这里的主要问题是会有 60 亿个排列,所以即使是最高效的程序也会遇到困难,因为它不仅要生成它们,而且实际上必须对它们做一些事情。例如,在您的脚本中,对 print 的调用是最慢的部分。如果将它们存储在一个文件中,它们可能至少需要 500 GB。你想用这些排列做什么?
  • 是的,我知道它将在 300GB 左右。我需要它们在一个文件中。实际上我必须这样做,因为我有一个 12 字的比特币 BIP39 助记符,我不记得单词的顺序,只记得单词。获得文件后,我想编写一个脚本来检查它们中的每一个是否符合 BIP39 标准的有效助记符。否则我的比特币会丢失:/
  • 这很酷。如果从文件中读取而不是直接在for p in permutations(items, 12) 下检查,那么检查每个排列的第二部分是否更容易编写?

标签: string text awk permutation words


【解决方案1】:

重复调用print 会使脚本变慢,因为每次调用都会在与要打印的系统对话时产生一些开销。如果您将所有排列集中到一个字符串中并打印一次该字符串,您将获得显着的改进。但即便如此,当您在屏幕上显示文本时,打印也是一项繁重的工作。仅写入文件或立即使用这些排列执行您计划执行的任何操作会更快。

还可以进行一些较小的改进。元组是一个非常混乱的字符串表示形式:您需要引号(这涉及检查字符串是否有自己的引号)、逗号和括号。用空格连接单词会更快。

再深入一点,最好是基于内置函数隐式循环,因为它们是用 C 编写的,而不是你自己用 Python 编写的循环。例如,map 比 for comprehension 更快 if 该函数也是一个快速内置函数,而不是 Python 函数(例如 lambda)。如果您有兴趣,请阅读this

将所有这些想法结合在一起,我们有:

with open('perms.txt', 'w') as out:
    out.write('\n'.join(map(' '.join, permutations(items, 7))))

这需要 8 秒才能生成 900 万个长度为 7 的排列。

【讨论】:

  • You get a significant improvement if you lump all the permutations into a single string and print that string once. - 你确定吗?由于动态字符串连接中的内存管理开销,你不会在 awk 中,我认为 python 也有......
  • 是的,print 有不错的开销。 IO之类的通常是一个问题。上面的答案是通过不断的改进得出的,每一个都是定时的。
  • 另外我认为join 在分配字符串之前会计算出字符串的长度,这样您就不会得到重复加倍的数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多