一个可能的散列函数可以是(假设只有英文单词)每个字母出现次数的排序计数。因此,对于“anagram”,您将生成[('a',3),('g',1),('n',1),('m',1),('r',1)]。
或者,您可以通过从您的词中生成一个位掩码来获得一个不精确的分组,其中位0-25表示该字母的存在或不存在(位0表示'a'至位25表示'z') 。但是,接下来你需要做更多的处理来分割每个哈希组以进一步区分例如从“太”到“从”。
这些想法都有帮助吗?记住任何特定的实现语言(我可以做C++,Python或Scala)?
编辑:添加了一些例子,Scala代码和输出:
OK:我在此刻Scala的模式,所以我敲东西了,做你问什么,但(啊哈)它如果你不熟悉Scala或函数式编程,可能不太清楚。
使用从这里的英文单词的大名单:http://scrapmaker.com/data/wordlists/twelve-dicts/2of12.txt
我对他们的运行此Scala代码(发生在脚本模式下使用的Scala 2.9,包括时间编制约5秒,约40000字的字典不是最有效的代码,而是首先想到的)。
// Hashing function to go from a word to a sorted list of letter counts
def toHash(b:String) = b.groupBy(x=>x).map(v => (v._1, v._2.size)).toList.sortWith(_._1 < _._1)
// Read all words from file, one word per line
val lines = scala.io.Source.fromFile("2of12.txt").getLines
// Go from list of words to list of (hashed word, word)
val hashed = lines.map(l => (toHash(l), l)).toList
// Group all the words by hash (hence group all anagrams together)
val grouped = hashed.groupBy(x => x._1).map(els => (els._1, els._2.map(_._2)))
// Sort the resultant anagram sets so the largest come first
val sorted = grouped.toList.sortWith(_._2.size > _._2.size)
for (set <- sorted.slice(0, 10))
{
println(set._2)
}
此转储出第10个集字谜(与大多数成员第一组)存在的:
List(caret, cater, crate, react, trace)
List(reins, resin, rinse, risen, siren)
List(luster, result, rustle, sutler, ulster)
List(astir, sitar, stair, stria, tarsi)
List(latrine, ratline, reliant, retinal)
List(caper, crape, pacer, recap)
List(merit, miter, remit, timer)
List(notes, onset, steno, stone)
List(lair, liar, lira, rail)
List(drawer, redraw, reward, warder)
注意,这里使用的第一个建议(字母数列表)不更复杂的位掩码方法。
编辑2:您可以在每个字(如联合申诉委员会的建议)的字符一个简单的排序代替散列函数和更清晰的/更快的代码获得相同的结果:
def toHash(b:String) = b.toList.sortWith(_<_)
问题不可怕在这里清楚。你能否重新说明目标? –
你的意思是说:我有一百万字的字典,我希望能够识别字典中相互对峙的所有单词集?例如。如果字典中包含:[tap,pat,pot,top],您希望看到[[tap,pat],[pot,top]]? –
是啊@Alex。我只想要有多少不同的字谜? – vijay