lua实现一个计算器

最近用lua写了一个计算器,可以完成(+ - * /)的功能,并且加入了对括号优先级的计算。

  1. 先定义打印函数和无括号的公式处理函数

无括号的公式处理函数:
定义两个表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
  1. 计算顺序,先乘除,后加减
-- 先乘除
	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. 括号优先级的处理
    原理:
    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))

测试

用lua写一个PID_后端

问题:
目前测试加减乘除加括号优先级,运算结果都没问题
只有-- 括号中运算结果是小数时会处理错误(缺乏带小数的数字处理,4*5.0),以后有时间再补充吧