【问题标题】:Running into an infinite loop while solving CryptArithmetic Problem in Python在 Python 中解决 CryptArithmetic 问题时陷入无限循环
【发布时间】:2022-01-06 06:53:11
【问题描述】:

我正在解决 LeetCode 的一个问题,https://leetcode.com/problems/verbal-arithmetic-puzzle/ 使用回溯。

这和 CryptArithmetic 问题是一样的,所以我会简单解释一下到底是什么问题。

class Solution:
    def isSolvable(self,words, result):
        characterMap={}
        uniqueString=""

        for word in words:
            for letter in word:
                if letter not in characterMap:
                    uniqueString+=letter
                    characterMap[letter]=-1
        
        for r in result:
            if r not in characterMap:
                uniqueString+=r
                characterMap[r]=-1
        
                
        self.words=words
        self.result=result
        self.uniqueString=uniqueString
        self.characterMap=characterMap
        self.usedDigit={i:False for i in range(10)}

        
        return self.isSolvableHelper(0)
    
    def getSum(self, word):
        sums=""
        for w in word:
            sums+=str(self.characterMap[w])
        
        return int(sums)
    
    def isSolvableHelper(self, idx):
        if(idx==len(self.uniqueString)):
            sumUp=0
            for w in self.words:
                sumUp+=self.getSum(w)
            
            resultSum=self.getSum(self.result)
            
            return True if(resultSum==sumUp) else False
        
        char=self.uniqueString[idx]
        for i in range(10):
            if(not self.usedDigit[i]):
                self.characterMap[char]=i
                self.usedDigit[i]=True
                self.isSolvableHelper(idx+1)
                self.usedDigit[i]=False
                self.characterMap[char]=-1

sol=Solution()
sol.isSolvable(['SEND','MORE'], "MONEY")

我考虑了与输入相同的示例,其中单词 array/list = ["SEND", "MORE"],结果是 MONEY

我遇到了一个无限循环,不确定发生在哪里,我怀疑 这可能是回溯开始的地方 这是输出,它只是继续运行

你能帮我看看我的逻辑有什么错误吗?

【问题讨论】:

  • 你能发一个minimal reproducible example吗?特别是,导致无限循环的函数的输入是什么?另外,是什么让您认为无限循环恰好发生在该行代码上?
  • 嗨,我已经更新了问题,添加了问题陈述和控制台中显示的输出,怀疑回溯块是问题所在
  • 不确定它是否在循环:代码的可能性数量是 10 的阶乘 / 阶乘 (10 - len(unique string) 相当多。例如:10!/(10 -2)!=10!/2!=10*9*7*6*5*4*3 = 1814400。因为字符串的长度是 8。

标签: python recursion backtracking


【解决方案1】:

当您找到解决方案时,您永远不会返回 True :在 isSolvableHelper 中:

            for i in range(10):
                if(not self.usedDigit[i]):
                    self.characterMap[char]=i
                    self.usedDigit[i]=True
                    # in the next line you do not test the returned value, so you do not know when you have finished
                    self.isSolvableHelper(idx+1)
                    self.usedDigit[i]=False
                    self.characterMap[char]=-1

添加测试:

            for i in range(10):
                if(not self.usedDigit[i]):
                    self.characterMap[char]=i
                    self.usedDigit[i]=True
                    If  self.isSolvableHelper(idx+1):
                        return True
                    self.usedDigit[i]=False
                    self.characterMap[char]=-1
            # Do not forget to return False 
            return False

您也可以只使用整数来优化 getSum:

    def getSum(self, word):
        #print("getSum({})".format(word))
        sums=0
        for w in word:
            sums = 10 * sums + self.characterMap[w]
    
        return sums

一些结果:(一个循环 = isSolvableHelper 中的一个条目)

SEND MORE = MONEY
Char map : {'E': 8, 'D': 7, 'M': 0, 'O': 3, 'N': 1, 'S': 2, 'R': 6, 'Y': 5}
nb loop : 730250

SIX SEVEN SEVEN = TWENTY
Char Mao : {'E': 8, 'I': 5, 'N': 2, 'S': 6, 'T': 1, 'W': 3, 'V': 7, 'Y': 4, 'X': 0}
nb loop : 4094645

THIS IS TOO = FUNNY
Char map : {'F': 0, 'I': 8, 'H': 6, 'O': 5, 'N': 1, 'S': 2, 'U': 4, 'T': 3, 'Y': 9}
nb loop : 2272068

LEET CODE = POINT
no char map
nb loop : 6235301

【讨论】:

  • 谢谢@Ptit Xav,这很有效,我刚刚开始了解回溯的概念,这对我帮助很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
相关资源
最近更新 更多