lua实现一个计算器
最近用lua写了一个计算器,可以完成(+ - * /)的功能,并且加入了对括号优先级的计算。
- 先定义打印函数和无括号的公式处理函数
无括号的公式处理函数:
定义两个表num和sig,一个存放数字,一个存放符号,读取公式字符串按照公式的顺序分别存字符和数字到两个表。这样两个表有隐式联系,比如
(3*1-2)num={3,1,2},sig={”*“,”-“},
(3*1-2)=num[1]..sig[1]..num[2]..sig[2]..num[3]
第i步计算:num[i]..sig[i]..num[i+1]
但是有例外情况,就是公式中有负数时(3*-2+1)做额外处理,符号部分还是存入sig,数字部分存入num
--打印函数
function printTable(t)
for i,v in pairs(t) do
print(v)
end
end
-- 1 、无括号的公式处理函数
function calculator(s)
-- 存放数字的表
local num={}
-- 存放符号的表
local sig={}
-- 给负号开头的数据进行优化 (-5)->(0-5)
if(string.find(s,"-")==1)
then
s="0"..s
end
if(string.find(s,"%a"))
then
print("格式错误!")
else
while(s) do
-- 处理数字,数字存入sum表中
if(string.find(s,"%d")==1)
then
-- 查找一个或多个数字
d1,d2=string.find(s,"%d*%d")
-- 插入表中
table.insert(num,string.sub(s,d1,d2))
-- 字符串缩短
s=string.sub(s,d2+1)
--处理(*-3)(/-3)(+-3)(--3)负数类型
-- 数字存入sum表中,符号存入sig表中
elseif(string.find(s,"%p%p%d*%d")==1)
then
d1,d2=string.find(s,"%p%p%d*%d")
-- 符号部分插入sig
table.insert(sig,string.sub(s,d1,d1))
-- 负数部分插入num
table.insert(num,string.sub(s,d1+1,d2))
s=string.sub(s,d2+1)
-- 处理单个符号,符号存入sig表中
elseif(string.find(s,"%p")==1)
then
d1,d2=string.find(s,"%p")
table.insert(sig,string.sub(s,d1,d2))
s=string.sub(s,d2+1)
else
print("输入有误")
end
-- 字符串截完后退出循环
if(#s==0)
then break end
end
end
- 计算顺序,先乘除,后加减
-- 先乘除
for i=1,#sig do
if(sig[i]=="*")
then
num[i]=num[i]*num[i+1]
table.remove(sig,i)
table.remove(num,i+1)
end
end
for i=1,#sig do
if(sig[i]=="/")
then
num[i]=num[i]/num[i+1]
table.remove(sig,i)
table.remove(num,i+1)
end
end
-- 乘除完 只剩加减 必须按顺序进行加减运算
while(#sig~=0) do
if(sig[1]=="+")
then
num[1]=num[1]+num[2]
table.remove(num,2)
table.remove(sig,1)
elseif(sig[1]=="-")
then
num[1]=num[1]-num[2]
table.remove(num,2)
table.remove(sig,1)
end
end
-- 返回表中最终的结果
return num[1]
end
- 括号优先级的处理
原理:
1、寻找s2中第一个“)”右括号下标M
2、在s2的第1~M个数中,寻找最后一个“(”左括号下标N
3、截取s2中MN之间的字符串,传入函数,得到的返回值替换该位置(删除括号)
4.、继续循环,知道查找不到“)”右括号为止
5、括号处理完,将无括号的字符串传入函数 得到最终结果
-- 2、接收输入的公式
print("请输入要计算的公式:")
s2=io.read()
-- 3、根据优先级先计算嵌套括号内的数据
while(string.find(s2,"%)")) do
-- 获取第一个右括号的下标
dr=string.find(s2,"%)")
-- 截取右括号之前的字符串
s11=string.sub(s2,1,dr)
-- 倒转字符串方便查询
sr11=string.reverse(s11)
-- 获取离第一个右括号下标最近的左括号下标
dl=#sr11-string.find(sr11,"%(")+1
-- 截取字符串中括号内数据
ns=string.sub(s2,dl+1,dr-1)
-- 传入计算器得到返回值
rs=calculator(ns)
-- 结果替换括号内容
s2=string.sub(s2,1,dl-1)..rs..string.sub(s2,dr+1)
-- print(s2)
end
-- 4、输出最终结果
print("最终结果:")
print(calculator(s2))
测试
问题:
目前测试加减乘除加括号优先级,运算结果都没问题
只有-- 括号中运算结果是小数时会处理错误(缺乏带小数的数字处理,4*5.0),以后有时间再补充吧