1

我想在我的电晕应用程序中评估一个数学字符串。现在我专注于三角函数,所以让我们让这个例子成为我们可能面临的最困难的例子:

local expr = "2sin(4pi+2)+7"

我的目标是以某种方式(或者)用一个pi --> math.pi开关来评估它,或者甚至将它分解。然而,分手会更加困难,因为它可能像上面一样复杂,但也可能只是sin(1)

所以我宁愿尽可能地接近pythoneval(expr)函数,但如果这不能发生,我很灵活。

4

2 回答 2

0

最简单的方法是替换sinmath.sin( piwithmath.pi等),添加缺少的乘号,然后运行它loadstring,但loadstring在 Corona 环境中不可用。

这意味着您需要为这些表达式编写自己的解析器。我在 Corona 论坛上找到了一个可以帮助您作为起点的讨论:这里,有一些细节和演示这里

于 2012-09-24T15:44:20.947 回答
0

这应该可以解决问题,它能够使用 lua 数学函数而无需放置“math.function”,因此 sqrt(100) 可以正常工作。我把它放在一起是因为我已经看到这个问题被问了太多次了。希望这会有所帮助:)

如果您有任何问题,请随时通过 rayaman99@gmail.com 与我联系

function evaluate(cmd,v) -- this uses recursion to solve math equations
    --[[ We break it into pieces and solve tiny pieces at a time then put them back together
        Example of whats going on
        Lets say we have "5+5+5+5+5"
        First we get this:
        5+5+5+5 +   5
        5+5+5   +   5
        5+5 +   5
        5   +   5
        Take all the single 5's and do their opperation which is addition in this case and get 25 as our answer
        if you want to visually see this with a custom expression, uncomment the code below that says '--print(l,o,r)'
    ]]
    v=v or 0
    local count=0
    local function helper(o,v,r)-- a local helper function to speed things up and keep the code smaller
        if type(v)=="string" then
            if v:find("%D") then
                v=tonumber(math[v]) or tonumber(_G[v]) -- This section allows global variables and variables from math to be used feel free to add your own enviroments
            end
        end
        if type(r)=="string" then
            if r:find("%D") then
                r=tonumber(math[r]) or tonumber(_G[r]) -- A mirror from above but this affects the other side of the equation
                -- Think about it as '5+a' and 'a+5' This mirror allows me to tackle both sides of the expression
            end
        end
        local r=tonumber(r) or 0
        if o=="+" then -- where we handle different math opperators
            return r+v
        elseif o=="-" then
            return r-v
        elseif o=="/" then
            return r/v
        elseif o=="*" then
            return r*v
        elseif o=="^" then
            return r^v
        end
    end
    for i,v in pairs(math) do
        cmd=cmd:gsub(i.."(%b())",function(a)
            a=a:sub(2,-2)
            if a:sub(1,1)=="-" then
                a="0"..a
            end
            return v(evaluate(a))
        end)
    end
    cmd=cmd:gsub("%b()",function(a)
        return evaluate(a:sub(2,-2))
    end)
    for l,o,r in cmd:gmatch("(.*)([%+%^%-%*/])(.*)") do -- iteration this breaks the expression into managable parts, when adding pieces into
        --print(":",l,o,r) -- uncomment this to see how it does its thing
        count=count+1 -- keep track for certain conditions
        if l:find("[%+%^%-%*/]") then -- if I find that  the lefthand side of the expression contains lets keep breaking it apart
            v=helper(o,r,evaluate(l,v))-- evaluate again and do the helper function
        else
            if count==1 then
                v=helper(o,r,l) -- Case where an expression contains one mathematical opperator
            end
        end
    end
    if count==0 then return (tonumber(cmd) or tonumber(math[cmd]) or tonumber(_G[cmd])) end
    -- you can add your own enviroments as well... I use math and _G
    return v
end
a=5
print(evaluate("2+2+2*2")) -- This still has work when it comes to pemdas; however, the use parentheses can order things!
print(evaluate("2+2+(2*2)"))-- <-- As seen here
print(evaluate("sqrt(100)"))
print(evaluate("sqrt(100)+abs(-100)"))
print(evaluate("sqrt(100+44)"))
print(evaluate("sqrt(100+44)/2"))
print(evaluate("5^2"))
print(evaluate("a")) -- that we stored above
print(evaluate("pi")) -- math.pi
print(evaluate("pi*2")) -- math.pi
于 2016-10-30T21:30:57.367 回答