开发者社区> 问答> 正文

有什么方法可以更有效地检查单词中的所有字母是否都在列表中?

对于研究论文,我模拟了Channel 4 Program Countdown的字母回合。本质上,是由9个随机字母组成的棋盘,玩家必须尝试找到由尽可能长的字母组成的单词。

我当前正在使用代码:

for word in sowpods:
        testboard = list(board)
        count = 0
        for letter in word:
            if letter in testboard:
                testboard.remove(letter)
                count += 1
        if len(word) == count:
            length.append(len(word))
    if len(length) == 0:
        return 0
    return max(length)

创建可以从板上创建的词典单词(导入到内核的SOWPODS .txt文件)列表,然后返回可能的最长单词以进行统计分析(这是模拟倒数轮功能的一部分) 。但是,从我的想象中,是由于重复的for循环,if语句和列表编辑,当按比例放大到500个左右的木板的较大样本时,这非常慢。有没有更有效的方法来检查是否可以从板上创建一个单词?

我尝试使用集合;我原来的测试是:

set(word) <= set(board)

但是此方法会被忽略,并且会重复,因此,例如,如果板子为[a,e,h,s,l,..),则尽管只有一个S可用,它仍会将“ Hassle”视为可能的单词。理想情况下,我会喜欢列表和集合之间的数据类型,其中顺序无关紧要,而相同元素的数量却无关紧要,但这似乎并不存在。

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 15:52:10 565 0
1 条回答
写回答
取消 提交回答
  • 可以实现的一种加速方法是重新组织逻辑,以便在遇到不匹配的字母时逐字母循环结束。平均而言,这将与不允许的字母数成正比,从而加快代码的速度。

    def wordsearch(board, sowpods):
        length = []
        for word in sowpods:
            testboard = list(board)
            count = 0
            for letter in word:
                if letter in testboard:
                    testboard.remove(letter)
                    count += 1
            if len(word) == count:
                length.append(len(word))
        if len(length) == 0:
            return 0
        return max(length)
    
    def find_matches(allowed, dictionary):
        allowed_list = list(allowed)
        match_words = []
        for word in dictionary:    
            good = True
            for letter in word:
                if letter not in allowed_list:
                    good = False
                    break
            if good == True:
                match_words.append(len(word))    
        return max(match_words)
    
    import timeit
    start_time = timeit.default_timer()
    allowed = 'iptneazol'
    result = wordsearch(allowed, sb_list)
    # code you want to evaluate
    elapsed = timeit.default_timer() - start_time
    print(elapsed)
    >>>0.6867701730000135
    
    start_time = timeit.default_timer()
    allowed = 'iptneazol'
    result = find_matches(allowed, sb_list)
    elapsed = timeit.default_timer() - start_time
    print(elapsed)
    >>>0.10806877499999246
    

    由于代码不会转换允许列表,因此这也解决了允许字母出现两次的问题。为了获得更高的效率,您可以将for循环重写为调用服务函数的列表理解,或者使用迭代器/生成器。

    回答来源:stackoverflow

    2020-03-24 15:52:19
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载