2009-10-28 112 views
0

我目前正试图深入挖掘python,并且我发现了一个对(hackthissite.org)的挑战,我试图破解它。我必须解读在提供的单词表中找到的10个单词。解密Python字解密器

def permutation(s): 
    if s == "": 
     return [s] 
    else: 
     ans = [] 
     for an in permutation(s[1:]): 
      for pos in range(len(an)+1): 
       ans.append(an[:pos]+s[0]+an[pos:]) 
     return ans 

def dictionary(wordlist): 
    dict = {} 
    infile = open(wordlist, "r") 
    for line in infile: 
     word = line.split("\n")[0] 
     # all words in lower case!!! 
     word = word.lower() 
     dict[word] = 1 
    infile.close() 
    return dict 

def main(): 
    diction = dictionary("wordlist.txt") 
    # enter all the words that fit on a line or limit the number 
    anagram = raw_input("Please enter space separated words you need to unscramble: ") 
    wordLst = anagram.split(None) 

    for word in wordLst: 
     anaLst = permutation(word) 
     for ana in anaLst: 
      if diction.has_key(ana): 
       diction[ana] = word 
       #print "The solution to the jumble is" , ana 
    solutionLst = [] 
    for k, v in diction.iteritems(): 
     if v != 1: 
      solutionLst.append(k) 
      print "%s unscrambled = %s" % (v, k) 
    print solutionLst 

main() 

功能排列看起来像是实际解密的代码块。你能帮我理解它在编程上如何解决这个问题吗?

+0

您的缩进被打破。 – SilentGhost 2009-10-28 15:23:12

+0

是的,要正确地粘贴python是很困难的。 – adam 2009-10-28 15:25:28

+0

如果您将'permutation'函数识别为正在执行实际工作的函数,您不能单独运行它并查看它返回的结果吗? – SilentGhost 2009-10-28 15:28:34

回答

3

造成这种情况的伪代码如下所示:

Load the word list (dictionary) 
Input the words to unscramble 
For each word: 
    Find every permutation of letters in that word (permutation) 
    For each permutation: 
    Add this permutation to the solution list if it exists in the dictionary 
Print the solutions that were found. 

字典()函数从一个文件填充你的单词列表。

permutation()函数返回给定单词中每个字母的排列。


置换()函数执行以下操作:

for an in permutation(s[1:]): 

S [1:]返回与截断的第一个字符的字符串。你会看到它使用递归来再次调用permutation(),直到没有字符从前面被截断为止。你必须知道递归来理解这一行。使用递归允许这个算法覆盖每一个字母,并且仍然很优雅。

for pos in range(len(an)+1): 

对于每个剩余的字母位置。

ans.append(an[:pos]+s[0]+an[pos:]) 

通过移动的第一个字母(我们前面截断)每个其他字母之间的位置生成置换。


因此,以“手表”为例。递归后,会有产生下面的话一个循环:

awtch atwch atcwh atchw

我所做的一切来生成这些字眼取第一个字母,并改变其位置。继续,结合截断字母,你会创造每一个排列。

(哇,这必须是我最长的答案了)

+0

谢谢......现在我的程序对我来说有点清晰了。 – adam 2009-10-28 15:38:41

+0

我添加了一个更详细解释permutation()函数的更新。我希望更清楚:D – Kai 2009-10-28 15:41:23

+0

非常感谢你,你对我的理解有了很大的帮助。再次感谢 – adam 2009-10-28 15:49:51

0

有一个更好的解决方案。如果有很多长词,此代码效率非常低。一个更好的想法是按字典顺序排列字典中的每个单词,这样'上帝'变成'dgo',并且对于乱码的单词也是这样。然后它是O(nlogn)为每个单词而不是O(n!)

0

我也为该网站编写了此代码。下面 工作代码:

def import_dictionary(): 
    dictionary = [] 
    try: 
     file = open("C:\\Users\\Mason\\Desktop\\diction.txt", "r")#location of your dictionary or provided wordlist 
     fileContents = file.readlines() #read text file and store each new line as a string 
    finally: 
     file.close() 
    for i in range(len(fileContents)): 
     dictionary.extend(fileContents[i].split()) #changes the list by removing \n's from line breaks in text file 
    return dictionary 

def import_scrambled_words(): 
    scrambledWords = [] 
    try: 
     file = open("C:\\Users\\Mason\\Desktop\\scrambled.txt", "r") #location of your scrambled word file 
     fileContents = file.readlines() #read text file and store each new line as a string 
    finally: 
     file.close() 
    for i in range(len(fileContents)): 
     scrambledWords.extend(fileContents[i].split()) #changes the list by removing \n's from line breaks in text file 
    return scrambledWords 

def unscramble_word(scrambledWord): 
    countToMatch = len(scrambledWord) 
    matchedWords = [] 
    string = "" 

    for word in dictionary: 
     count = 0 
     for x in scrambledWord: 
      if x in word: 
       count += 1 
      if count == countToMatch: 
       matchedWords.append(word) 
       break 
    for matchedWord in matchedWords: 
     if len(matchedWord) == len(scrambledWord): 
      print(matchedWord) 
      string = matchedWord 
      break #this returns only one unscrambles word 
    return string 

if __name__ == '__main__': 
    finalString = "" 
    try: 
     scrambled = import_scrambled_words() 
     print(scrambled) 
     dictionary = import_dictionary() 
     for x in scrambled: 
      finalString += unscramble_word(x) 
      finalString +=", " 
     len(finalString) 

     print(finalString) 

    except Exception as e: 
     print(e) 

此代码将从炒字保存的文件读取,并检查它针对的词表(我使用的字典在我的情况只是要另计)。为了在分配的30秒内击败挑战,我从hackThissite复制粘贴并粘贴到我的炒字文件。保存。运行程序并复制粘贴我的python控制台的输出。