【问题标题】:multilevel caesar cipher多级凯撒密码
【发布时间】:2011-07-11 06:35:51
【问题描述】:

嘿,我正在尝试解码多级凯撒密码。我的意思是一串字母可能已经移动了几次,所以如果我说 apply_shifts[(2,3),(4,5)],这意味着我将第二个字母的所有内容都移动了 3,然后是第 4 个字母 5。这是我目前的代码。

def find_best_shifts_rec(wordlist, text, start):
    """
    Given a scrambled string and a starting position from which
    to decode, returns a shift key that will decode the text to
    words in wordlist, or None if there is no such key.

    Hint: You will find this function much easier to implement
    if you use recursion.

    wordlist: list of words
    text: scambled text to try to find the words for
    start: where to start looking at shifts
    returns: list of tuples.  each tuple is (position in text, amount of shift)
    """

    for shift in range(27):
        text=apply_shifts(text, [(start,-shift)])
        #first word is text.split()[0]
        #test if first word is valid.  if not, go to next shift

        if is_word(wordlist,text.split()[0])==False:
            continue

        #enter the while loop if word is valid, otherwise never enter and go to the next shift
        i=0
        next_index=0
        shifts={}
        while is_word(wordlist,text.split()[i])==True:
            next_index+= len(text.split()[i])
            i=i+1
            #once a word isn't valid, then try again, starting from the new index.
            if is_word(wordlist,text.split()[i])==False:
                shifts[next_index]=i
                find_best_shifts_rec(wordlist, text, next_index)

    return shifts

我的问题是

1) 我的代码运行不正常,我不明白为什么会出现问题(它没有进入我的 while 循环) 和 2)我不知道如何测试我的“最终班次”(例如我的字符串的最后一部分)是否都是有效的单词,我也不知道如何从那里再次回到循环的开头.

我们将不胜感激。

【问题讨论】:

  • 家庭作业?您还应该确保您的代码格式正确。看起来不是全部缩进。
  • 是的,这是家庭作业。我不是要求别人为我做这件事,只是需要帮助看看我的代码有什么问题。
  • 函数“is_word”是否提供给您?它看起来像什么?
  • 是的,is_word(wordlist, word) 是提供给我的。它只是检查单词是否在给定的单词列表中。

标签: python


【解决方案1】:

我认为问题在于您总是在整个文本上工作,但在文本内部的某个开始处应用(新)移位。因此,您的支票 is_word(wordlist,text.split()[0])始终检查第一个单词,这当然是您第一次轮班之后的一个单词。

您需要做的是获取新起点之后的第一个单词,因此请检查文本中实际未处理的部分。

编辑

我注意到的另一个问题是您尝试找到正确班次的方式:

for shift in range(27):
    text=apply_shifts(text, [(start,-shift)])

所以你基本上想尝试从 0 到 26 的所有转换,直到第一个单词被接受。可以这样做,但请注意,在第一次尝试移位后,文本已更改。因此,您不是按1, 2, 3, ... 移动它,而是按1, 3, 6, 10, ... 移动它,这当然不是您想要的,您当然会在多次执行一些相同的移动时错过一些移动。

因此,您需要暂时移动您的文本并检查该临时文本的状态,然后再继续使用该文本。或者,您也可以改为使用1

编辑²

我注意到的另一个问题是您尝试使用递归来获得最终结果的方式。通常递归(带有结果)的工作方式是您不断调用函数本身并传递返回值,或者收集结果。在您的情况下,由于您希望有多个值,而不仅仅是来自内部某处的单个值,您需要收集每个移位结果。

但是现在,您正在丢弃递归调用的返回值,只返回最后一个值。因此,请存储所有值并确保不会丢失它们。

【讨论】:

  • 我还想输入“如果测试的第一个单词在任何班次下都无效”的话,然后回到之前的循环。我只是不知道最好的方法。
【解决方案2】:

递归函数的伪代码:

coded_text = text from start-index to end of string
if length of coded_text is 0, return "valid solution (no shifts)"

for shift in possible_shifts:
    decoded_text = apply shift of (-shift) to coded_text
    first_word = split decoded_text and take first piece
    if first_word is a valid word:
        rest_of_solution = recurse on (text preceding start-index)+decoded_text, starting at start+(length of first_word)+1
        if rest_of_solution is a valid solution
            if shift is 0
                return rest_of_solution
            else
                return (start, -shift mod alphabet_size) + rest_of_solution

# no valid solution found
return "not a valid solution"

请注意,这保证给出由有效单词组成的答案 - 不一定是原始字符串。一个具体的例子:可以解码“a add hat”来代替“a look at”。

【讨论】:

    猜你喜欢
    • 2014-04-11
    • 1970-01-01
    • 2014-03-07
    • 2020-05-31
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 2013-03-13
    相关资源
    最近更新 更多