多级凯撒密码

时间:2011-03-08 16:54:58

标签: python

嘿,我正在尝试解码多级凯撒密码。我的意思是一串字母本来可以移几次,所以如果我说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)我不知道如何测试我的“最终转换”(例如我的字符串的最后一部分)是否都是有效的单词而且我也不知道如何从那里再到我的循环的最开始

非常感谢帮助。

2 个答案:

答案 0 :(得分:0)

我认为问题在于你总是处理整个文本,但是在文本的某个开头应用(新)移位。因此,您的支票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

edit²

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

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

答案 1 :(得分:0)

递归函数的伪代码:

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"

请注意,这可以保证给出由有效单词组成的答案 - 不一定是原始字符串。一个具体的例子:'添加帽'可以解码,而不是“看看”。