第一步:确定优先级的函数,其中( 优先级最低。
public Boolean Priority(String ch1, String ch2)
{
switch (ch1)
{
case "(":
code1 = 1;
break;
case "+":
case "-":
code1 = 2;
break;
case "×":
case "÷":
code1 = 3;
break;
}
switch (ch2)
{
case "(":
code2 = 1;
break;
case "+":
case "-":
code2 = 2;
break;
case "×":
case "÷":
code2 = 3;
break;
}
if (code1 > code2)
{
return true;
}
else
{
return false;
}
}
第二步,把输入好的中缀表达式字符串转换成后缀表达式字符串。这里t1.Text是我输入的字符串,str1是我定义的全局字符串变量,赋值为空,待会把后缀表达式拼到str1上。
//中缀转后缀方法
public void Change()
{
String str = t1.Text;
string[] sz = splitFunc(str).Split('\n');
for (int i = 0; i <= sz.Length - 1; ++i)
{
if (string.IsNullOrEmpty(sz[i])) //分隔后为空的元素剔除
continue;
else if (isNumber(sz[i])) //纯数字直接入队列
str1 += sz[i] + ',';
else
{
switch (sz[i])
{
case "+": //加减乘除,按照优先级来操作。
if (stack2.IsEmpty())
{
stack2.Push(sz[i]);
} else {
String ch = (String)stack2.Peek();
if (ch != "(")
{
if (Priority(sz[i], ch))
{
stack2.Push(sz[i]);
}
else
{
while (!Priority(sz[i], ch))
{
str1 += stack2.Pop();
str1 += ',';
ch = (String)stack2.Peek();
if (ch == "(" || ch == null)
break;
}
stack2.Push(sz[i]);
}
}
else
{
stack2.Push(sz[i]);
}
}
break;
case "-":
if (stack2.IsEmpty())
{
stack2.Push(sz[i]);
}
else
{
String ch = (String)stack2.Peek();
if (ch != "(")
{
if (Priority(sz[i], ch))
{
stack2.Push(sz[i]);
}
else
{
while (!Priority(sz[i], ch))
{
str1 += stack2.Pop(); str1 += ',';
ch = (String)stack2.Peek();
if (ch == "(" || ch == null)
break;
}
stack2.Push(sz[i]);
}
}
else
{
stack2.Push(sz[i]);
}
}
break;
case "×":
if (stack2.IsEmpty())
{
stack2.Push(sz[i]);
}
else
{
String ch = (String)stack2.Peek();
if (ch != "(")
{
if (Priority(sz[i], ch))
{
stack2.Push(sz[i]);
}
else
{
while (!Priority(sz[i], ch))
{
str1 += stack2.Pop(); str1 += ',';
ch = (String)stack2.Peek();
if (ch == "(" || ch == null)
break;
}
stack2.Push(sz[i]);
}
}
else
{
stack2.Push(sz[i]);
}
}
break;
case "÷":
if (stack2.IsEmpty())
{
stack2.Push(sz[i]);
}
else
{
String ch = (String)stack2.Peek();
if (ch != "(")
{
if (Priority(sz[i], ch))
{
stack2.Push(sz[i]);
}
else
{
while (!Priority(sz[i], ch))
{
str1 += stack2.Pop(); str1 += ',';
ch = (String)stack2.Peek();
if (ch == "(" || ch == null)
break;
}
stack2.Push(sz[i]);
}
}
else
{
stack2.Push(sz[i]);
}
}
break;
case "(": //左括号,直接入栈
stack2.Push(sz[i]);
break;
case ")": //右括号,出栈直到遇见 ( ,跳出循环后把左括号出栈。
if (!stack2.IsEmpty())
{
String ch = (String)stack2.Peek();
while (ch != "(")
{
str1 += stack2.Pop(); str1 += ',';
ch = (String)stack2.Peek();
}
stack2.Pop();
}
break;
}
}
}
while (!stack2.IsEmpty()) //清空栈,把剩余的符号拼上去。
{
str1 += stack2.Pop(); str1 += ',';
}
}
所需函数
public static string splitFunc(string tmp) //分割字符串的方法
{
string sRet = tmp;
sRet = sRet.Replace("=", "\n=\n");
sRet = sRet.Replace("+", "\n+\n");
sRet = sRet.Replace("-", "\n-\n");
sRet = sRet.Replace("×", "\n×\n");
sRet = sRet.Replace("÷", "\n÷\n");
sRet = sRet.Replace("(", "\n(\n");
sRet = sRet.Replace(")", "\n)\n");
return sRet;
}
//判断是不是数字
public bool isNumber(string tmp)
{
return Regex.IsMatch(tmp, @"[0-9]+[.]{0,1}[0-9]*"); //{0,1}指小数点有或没有
}
以上就是全部的代码了,转化成后缀表达式后即可通过栈方便计算了。
需要理解原理的朋友 可以看这位大神的博客 👇
https://blog.csdn.net/xiaohusaier/article/details/76090804
附录:栈的定义
class Stack
{
int maxsize; //顺序栈的容量
object[] data; //数组,用于存储栈中的数据
int top; //指示栈顶
public object this[int index]
{
get { return data[index]; }
set { data[index] = value; }
}
//使用构造器初始化栈
public Stack(int size)
{
data = new object[size];
maxsize = size;
top = -1;
}
//获得栈顶元素
public object Peek()
{
return data[top];
}
//判断顺序栈是否为空
public bool IsEmpty()
{
if (top == -1)
{
return true;
}
else
{
return false;
}
}
//判断顺序栈是否为满
public bool IsFull()
{
if (top == maxsize - 1)
{
return true;
}
else
{
return false;
}
}
//入栈操作
public void Push(object e)
{
if (IsFull())
{
return;
}
data[++top] = e;
}
//出栈操作,并返回出栈的元素
public object Pop()
{
object temp = null;
if (IsEmpty())
{
return temp;
}
temp = data[top];
top--;
return temp;
}