猿问

如何替换“x!” 智能地使用“math.factorial(x)”

我目前正在 Python 中实现一个图形计算器,您可以在其中键入自然表达式并对其进行评估。这对于大多数函数或运算符都不是问题,但由于阶乘函数由!操作数后的a 表示,因此这更加困难。

我所拥有的是一个包含函数的字符串,例如:'(2x + 1)!'需要替换为:'math.factorial((2x + 1))'

但是,该字符串还可能包含其他术语,例如:'2*x + (2x + 1)! - math.sin(x)' 并且阶乘术语可能不一定包含括号:'2!'

我一直在努力寻找解决这个问题的方法,但无济于事,我认为该string.replace()方法不能直接做到这一点。我寻求的东西是否过于雄心勃勃,或者有什么方法可以达到我想要的结果?


有只小跳蛙
浏览 193回答 2
2回答

绝地无双

你的问题有两个层次的答案:(1)解决你当前的问题;(2) 解决您的一般问题。(1) 非常简单 - 通常用于进行字符串模式匹配和替换的最常见、最通用的工具是正则表达式(RE)。您只需定义您正在寻找的模式、您想要的模式,然后将您的字符串传递给 RE 引擎。Python 有一个内置的RE 模块,称为re. 大多数语言都有类似的东西。某些语言(例如 Perl)甚至将其作为语言语法的核心部分。模式是一系列特定字符或非特定(“通配符”)字符。因此,在您的情况下,您需要特定 '!' 之前的非特定字符。特点。您似乎建议“之前”在您的情况下表示所有非空白字符,或者如果前面的字符是 ')',则该字符与前面的 '(' 之间的所有字符。所以让我们构建该模式,从没有括号的版本开始:[\w] - the set of characters which are letters or numbers (we need a set of       characters that doesn't include whitespace or ')' so I'm taking some       liberty to keep the example simple - you could always build your own       more complex set with the '[]' pattern)+    - at least one of them!    - the '!' character然后是带括号的版本:\(  - the literal '(' character, as opposed to the special function that ( has.   - any character+   - at least one of them?   - but dont be "greedy", ie. only take the smallest set of characters that      match the pattern (will work out to be the closest pair of parentheses)\)  - the closing ')' character!   - the '!' character然后我们只需要把它们放在一起。我们|用来匹配第一个模式或第二个模式。我们使用(和)来表示我们想要“捕获”的模式部分——它是 '!' 之前的那一点。以及我们稍后要使用的括号内。所以你的模式变成:([\w]+)!|\((.+?)\)!别担心,RE 表达式总是看起来像是有人刚刚捣碎了键盘。有一些很棒的工具,比如RegExr,可以帮助分解复杂的 RE 表达式。最后,您只需要获取捕获并将它们粘贴到“math.factorial”中即可。\x表示第xth 场比赛。如果第一个模式匹配,\2则为空白,反之亦然,因此我们可以同时使用它们。math.factorial(\1\2)就是这样!这里是如何在 Python 中运行 RE 的(注意r字符串阻止 Python 尝试将其\作为转义序列进行处理):import rere.sub(r'([\w]+)!|\((.+?)\)!', r'math.factorial(\1\2)', '2*x + (2x + 1)! - math.sin(x) + 2!')re.sub采用三个参数(加上一些此处未使用的可选参数):RE 模式、替换字符串和输入字符串。这产生:'2*x + math.factorial(2x + 1) - math.sin(x) + math.factorial(2)'这是我相信你所追求的。现在,(2)更难了。如果您真的打算实现一个以字符串作为输入的计算器,那么您很快就会被正则表达式淹没。在可以输入的内容和 Python 可以解释的内容之间会有很多例外和变化,最终你会得到一些非常脆弱的东西,在第一次与用户接触时就会失败。如果您不打算拥有用户,那么您就非常安全 - 您可以坚持使用有效的模式。如果不是,那么您会发现模式匹配方法有点限制。一般来说,您要解决的问题称为词法分析(或者更全面地,作为词法分析、句法分析和语义分析的三个步骤过程)。解决这个问题的标准方法是使用一种称为递归下降解析的技术。有趣的是,Python 解释器在解释上述re语句时执行的正是这个过程——编译器和解释器都执行相同的过程,将字符串转换为可由计算机处理的标记。你会在网上找到很多教程。它比使用 RE 稍微复杂一些,但允许更广泛的泛化。您可能想从这里的非常简短的介绍开始。

qq_花开花谢_0

您可以删除括号并以线性形式计算所有内容,这样在解析括号时它将评估操作数,然后应用阶乘函数 - 按照写入的顺序。或者,您可以获得!字符串中阶乘的索引,然后如果之前索引处的字符是一个 )右括号,您就知道在应用 math.factorial() 之前需要计算一个括号内的操作数。
随时随地看视频慕课网APP

相关分类

Python
我要回答