[英]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.