简体   繁体   English

在Clojure中评估数学字符串

[英]Evaluate math string in Clojure

I need to implement a function called eval-math-string in Clojure, which takes a math string as input and evaluates it: (eval-math-string "7+8/2") => 11 我需要在Clojure中实现一个称为eval-math-string的函数,该函数将一个数学字符串作为输入并对其求值: (eval-math-string "7+8/2") => 11

So I've managed to break apart an expression using re-seq, and now I want to evaluate it using Incanter. 因此,我设法使用re-seq分解了一个表达式,现在我想使用Incanter对其求值。 However, I have an expression like ("7" "+" "8" "/" "2"), but Incanter needs an expression like ($= 7 + 8 / 2), where $= is the incanter keyword. 但是,我有一个类似(“ 7”“ +”“ 8”“ /”“ 2”)的表达式,但是Incanter需要一个类似($ = 7 + 8/2)的表达式,其中$ =是incanter关键字。 How can I feed the list of one-character strings into a list including $= so that it executes properly. 我如何将一个单字符字符串的列表提供给包含$ =的列表,以便其正确执行。 If the arguments are strings, the function won't work, but I can't convert +, *, / etc. to numbers, so I'm a little stuck. 如果参数是字符串,则该函数将不起作用,但是我无法将+,*,/等转换为数字,因此有点卡住了。

Does anyone know how I can do this, or if there is a better way to do this? 有谁知道我该怎么做,或者是否有更好的方法来做到这一点?

Incanter's $= macro just calls the infix-to-prefix function , so all you need to do is convert your list of strings to a list of symbols and numbers, then call infix-to-prefix . Incanter的$=仅调用了infix-to-prefix函数 ,因此您所需要做的就是将字符串列表转换为符号和数字列表,然后调用infix-to-prefix

I'm going to assume that the input is just a flat list of strings, each of which represents either an integer (eg "7" , "8" , "2" ) or a symbol (eg "+" , "/" ). 我将假设输入只是一个平面的字符串列表,每个字符串表示一个整数(例如"7""8""2" )或一个符号(例如"+""/" )。 If that assumption is correct, you could write a conversion function like this: 如果该假设正确,则可以编写如下转换函数:

(defn convert [s]
  (try
    (Long/parseLong s)
    (catch NumberFormatException _
      (symbol s))))

Example: 例:

(infix-to-prefix (map convert ["7" "+" "8" "/" "2"]))

Of course, if you're just writing a macro on top of $= , there's no need to call infix-to-prefix , as you would just be assembling a list with $= as the first item. 当然,如果您只是在$=之上编写一个宏,则无需调用infix-to-prefix ,因为您只需将$=作为第一项组装一个列表。 I'm going to assume that you already have a function called math-split that can transform something like "7+8/2" into something like ["7" "+" "8" "/" "2"] , in which case you can do this: 我将假设您已经有了一个称为math-split的函数,该函数可以将诸如"7+8/2"转换为["7" "+" "8" "/" "2"] ,在这种情况下,您可以执行以下操作:

(defmacro eval-math-string [s]
  `($= ~@(map convert (math-split s))))

Example: 例:

(macroexpand-1 '(eval-math-string "7+8/2"))
;=> (incanter.core/$= 7 + 8 / 2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM