【问题标题】:Python - How to make crossword solver faster [closed]Python - 如何使填字游戏求解器更快[关闭]
【发布时间】:2013-02-26 21:22:20
【问题描述】:

我有以下功能,它是填字游戏求解器的一部分:

def CrosswordPossibleWords(p_words, p_cw_words):
    """For each word found in the crossword, find the possible words and keep track of the one with the minimum possible words.

    Keyword arguments:
    p_words    -- The dictionary words.
    p_cw_words -- The crossword word attributes.
    """
    l_min = 999999999
    l_min_index = -1
    l_index = 0
    l_choices = []
    for l_cw_word in p_cw_words:
        if l_cw_word[2] >= l_min_length and '-' in l_cw_word[4]:
            pattern = re.compile('^' + l_cw_word[4].replace('.', '%').replace('-', '.').upper() + '$', re.UNICODE)
            l_choice = []
            for l_word in [w for w in p_words if len(w) == len(l_cw_word[4])]:
                if re.match(pattern, l_word):
                    l_choice.append(l_word)
            l_choices.append(l_choice)
            if len(l_choice) < l_min:
                l_min_index = l_index
                l_min = len(l_choice)
        else:
            l_choices.append([])
        l_index = l_index + 1
    return (l_choices, l_min_index)

填字游戏的形式是:

[row, col, length, direction, word]

如果我不能解出某个单词,我有一个'.',如果我不知道那个字母,我有一个'-'

如何使这段代码更快?目前运行大约需要 2.5 秒。正在考虑使用 numpy 字符串;因为显然 numpy 快了 10 倍,但我对 numpy 一无所知,也不知道我是否能够使用所有当前的字符串函数。

有什么想法吗?

【问题讨论】:

  • numpy 在做什么方面快 10 倍,究竟是什么?找出您的程序在哪里/如何花费时间,并对其进行优化。

标签: python


【解决方案1】:

您可以在调用此函数之前按字长对字典进行分区,因此不必在每次调用时都重新执行此操作。

【讨论】:

    【解决方案2】:

    虽然我同意 Scott Hunter 的观点,但您可能正在寻找这样的东西,其中列表被替换为 dicts:

    def CrosswordPossibleWords(p_words, p_cw_words):
        """For each word found in the crossword, find the possible words and keep track of the one with the minimum possible words.
    
        Keyword arguments:
        p_words    -- The dictionary words.
        p_cw_words -- The crossword word attributes.
        """
        l_min = 999999999
        l_min_index = -1
        l_index = 0
        l_choices = {}    # using dict instead of list
        for l_cw_word in p_cw_words:
            if l_cw_word[2] >= l_min_length and '-' in l_cw_word[4]:
                pattern = re.compile('^' + l_cw_word[4].replace('.', '%').replace('-', '.').upper() + '$', re.UNICODE)
                    l_choice = {}  # using dict instead of list
    
                for l_word in [w for w in p_words if len(w) == len(l_cw_word[4])]:
                    if re.match(pattern, l_word):
    
                        l_choice[l_word]=None
    
                l_choices[l_choice]=None
    
                if len(l_choice) < l_min:  ##
                    l_min_index = l_index  ## Get rid of this.
                    l_min = len(l_choice)  ##
            else:
                l_choices.append([])    # why append empty list?
            l_index = l_index + 1
            l_choices=list(l_choices.keys())   # ...you probably need the list again...
        return (l_choices, l_min_index)
    

    【讨论】:

    • 你是说字典比列表快吗?
    • 相当多 :-) 在帖子中:stackoverflow.com/questions/513882/… 解释了计算复杂性,其中搜索列表随列表长度线性增长。相比之下,字典具有恒定的查找时间。
    • 附言。你会收到一些关于我在你的文本中所做的更改的错误消息,但它应该能让你继续前进。
    • 你可以使用一个字典作为另一个字典的键吗?
    • 由于不需要关联,集合不会有同样的速度提升和更易于使用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多