程序员的算法趣题Q13: 满足字母算式的解法

程序 程序 1315 人阅读 | 0 人回复

<
目次

1. 成绩描摹
2. 解题思绪
3. 代码及测试
4. 劣化

1. 成绩描摹

        所谓字母算式,便是用字母表示的算式,划定规矩是不异字母对应不异数字,不同字母对应不同数字,而且第一名字母的对应数字不克不及是 0
        比如给定算式 We * love = CodeIQ,则能够对应挖高低里那些数字以使之建立。
        W = 7, e = 4, l = 3, o = 8, v = 0, C = 2, d = 1, I = 9, Q = 6
        如许一去,我们就可以获得 74 * 3804 = 281496 如许的等式。使那个字母算式建立的解法只要那一种。
        供使上面那个字母算式建立的解法有几种?
        READ + WRITE + TALK = SKILL
2. 解题思绪

        本题解着眼于通用的处理计划,即不只限于以上表达式,而是随便的字符串表达式(条件式确实可以代表正当的算法,比如道运算符不克不及连续呈现,等等)。
根本步调以下:
        Step1: 从输进字符串中提掏出表示数字(即除运算符战等号中)(没有反复, or unique)字符会萃
        Step2: 遍历以上一切字符取数字(0~9)的映照方法,假定有k个字符,则有P(10,k)平分列,每种排列对应一种映照方法
            Step2-1将每种映照方法代进到输进字符串获得字符串算式
            Step2-2 判定所获得的字符串算式能否是正当的
            Step2-3 别离评价字符串算式的LHS(Left-hand-side:左脚边表达式)战RHS(Right-hand-side:左脚边表达式)并判定能否相称

        正在Step2顶用python itertools模块中的permutation()天生一切的组开。
        正在Step2-3顶用pyhton内乱置的eval()函数停止字符串情势的算式值的评价
        正在 Step2-2中判定字符串表达式能否正当根据的划定规矩是多位数字的操纵数的第一个字母不克不及为0。首先基于‘=’的地位朋分获得LHS战RHS。
        RHS中由于出有运算符以是比力简朴,只需有多位数字(少度年夜于1)且尾位为0便表示长短法表达式。
        LHS的状况比力庞大,分以下三种状况思索:

  • 第一个操纵数的判定:假如LHS[0]为0且LHS[1]仍为数字则表白必定不法
  • 后来,搜刮每一个运算符,假如运算符后的第一个字符为0且第两个字符仍为数字,则为不法
  • LHS的最初一个字符不克不及为操纵符—那个判定,基于以下假定其实其实不需求
        当然以上判定办法是基于本输进字符串表达式必定能够表告竣一个正当的算式,比如没有会有两个连续的运算符呈现,等等。
3. 代码及测试

        
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sun Sep  5 08:39:27 2021
  4. @author: chenxy
  5. """
  6. import sys
  7. import time
  8. import datetime
  9. import math
  10. # import random
  11. from   typing import List
  12. # from   queue import Queue
  13. # from   collections import deque
  14. import itertools as it
  15. class Solution:
  16.     def stringEquation(self, strEqu:str):
  17.         """
  18.         strEqu: Equation in the form of string with character representing digit,
  19.                 assuming case insensitive.
  20.                 Also it is assumed that only integer division is considered
  21.         :ret: The total number of IP satisfying the requirement
  22.         """               
  23.         # Step1: extract the alphabeta characters from the string equation   
  24.         s = strEqu.upper() # Transfer to all uppercase for the convenience of processing        
  25.         cLst = []
  26.         for k in range(len(s)):            
  27.             if s[k].isalpha() and s[k] not in cLst:
  28.                 cLst.append(s[k])
  29.             if s[k] == &#39;=&#39;:
  30.                 equalSignIndex = k
  31.         # print(cLst)
  32.                
  33.         nums = 0
  34.         mapping = []
  35.         for p in it.permutations([k for k in range(10)], len(cLst)):
  36.             # print(p)
  37.             # Substitute c<->digit mapping back to the input string equation
  38.             # left-hand-side expression, before &#39;=&#39;            
  39.             lhs = s[0:equalSignIndex]
  40.             for k in range(len(cLst)):
  41.                 lhs = lhs.replace(cLst[k], str(p[k]))
  42.                
  43.             # right-hand-side expression, after &#39;=&#39;
  44.             rhs = s[equalSignIndex+1:]
  45.             for k in range(len(cLst)):
  46.                 rhs = rhs.replace(cLst[k], str(p[k]))               
  47.             
  48.             # print(lhs, rhs)
  49.             if len(rhs) > 1 and rhs[0] == &#39;0&#39; : # The first digit must be non-zero in multi-digit case
  50.                 # print(&#39;1&#39;)
  51.                 continue
  52.             if len(lhs) > 1 and lhs[0] == &#39;0&#39; and lhs[1].isdigit():
  53.                 # print(&#39;2&#39;)
  54.                 continue
  55.             if not lhs[-1].isdigit():
  56.                 # print(&#39;3&#39;, lhs, lhs[-1].isdigit() )
  57.                 continue
  58.                         
  59.             lhs_valid = True
  60.             for k in range(len(lhs)-2):
  61.                 if (not lhs[k].isdigit()) and lhs[k+1]==&#39;0&#39; and lhs[k+2].isdigit():
  62.                     # print(&#39;invalid lhs:&#39;, lhs)
  63.                     lhs_valid = False
  64.                     break
  65.             if not lhs_valid:
  66.                 continue
  67.             
  68.             # print(&#39;valid:&#39;, lhs, rhs, eval(lhs), eval(rhs))
  69.             if eval(lhs) == eval(rhs):
  70.                 nums = nums + 1
  71.                 mapping.append((cLst,p,lhs+&#39;=&#39;+rhs))
  72.         
  73.         return nums, mapping
复造代码
  1. if __name__ == &#39;__main__&#39;:        
  2.             
  3.     sln    = Solution()            
  4.     tStart = time.time()
  5.     strEqu = &#39;A*B=C&#39;
  6.     nums, mapping = sln.stringEquation(strEqu)
  7.     tCost  = time.time() - tStart
  8.     print(&#39;nums={0}, tCost = {1:6.3f}(sec)&#39;.format(nums,tCost))   
  9.     for item in mapping:
  10.         print(&#39;\t&#39;,item)
  11.    
  12.     tStart = time.time()
  13.     strEqu = &#39;We*love=CodeIQ&#39;
  14.     nums, mapping = sln.stringEquation(strEqu)
  15.     tCost  = time.time() - tStart
  16.     print(&#39;nums={0}, tCost = {1:6.3f}(sec)&#39;.format(nums,tCost))   
  17.     for item in mapping:
  18.         print(&#39;\t&#39;,item)
  19.    
  20.     tStart = time.time()
  21.     strEqu = &#39;READ+WRITE+TALK=SKILL&#39;
  22.     nums, mapping = sln.stringEquation(strEqu)
  23.     tCost  = time.time() - tStart
  24.     print(&#39;nums={0}, tCost = {1:6.3f}(sec)&#39;.format(nums,tCost))        
  25.     for item in mapping:
  26.         print(&#39;\t&#39;,item)   
复造代码
nums=10, tCost = 46.159(sec)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (1, 6, 3, 2, 4, 9, 7, 8, 0, 5), &#39;1632+41976+7380=50988&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (2, 5, 4, 3, 7, 0, 6, 9, 1, 8), &#39;2543+72065+6491=81099&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (4, 9, 0, 5, 2, 6, 8, 1, 7, 3), &#39;4905+24689+8017=37611&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (5, 0, 9, 4, 7, 3, 1, 6, 2, 8), &#39;5094+75310+1962=82366&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (5, 0, 9, 6, 3, 7, 1, 8, 2, 4), &#39;5096+35710+1982=42788&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (5, 1, 8, 0, 6, 9, 2, 4, 3, 7), &#39;5180+65921+2843=73944&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (5, 2, 7, 0, 8, 1, 3, 6, 4, 9), &#39;5270+85132+3764=94166&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (7, 0, 9, 2, 3, 5, 1, 8, 6, 4), &#39;7092+37510+1986=46588&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (7, 0, 9, 2, 4, 3, 1, 8, 6, 5), &#39;7092+47310+1986=56388&#39;)
     ([&#39;R&#39;, &#39;E&#39;, &#39;A&#39;, &#39;D&#39;, &#39;W&#39;, &#39;I&#39;, &#39;T&#39;, &#39;L&#39;, &#39;K&#39;, &#39;S&#39;], (9, 7, 2, 8, 1, 4, 6, 0, 5, 3), &#39;9728+19467+6205=35400&#39;)

4. 劣化

        以上固然得出的准确的结果,可是运转速率有面衰,需求思索进一步的劣化。

        上一篇:Q12: 仄圆根数字
        下一篇:Q14: 国名接龙
        本系列总目次参见:法式员的算法趣题:详细阐发战Python齐解

免责声明:假如进犯了您的权益,请联络站少,我们会实时删除侵权内乱容,感谢协作!
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,按照目前互联网开放的原则,我们将在不通知作者的情况下,转载文章;如果原文明确注明“禁止转载”,我们一定不会转载。如果我们转载的文章不符合作者的版权声明或者作者不想让我们转载您的文章的话,请您发送邮箱:Cdnjson@163.com提供相关证明,我们将积极配合您!
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。
回复 关闭延时

使用道具 举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则