数据结构习作之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (技术含量少许)
今天看到博客堂在讨论
《动态计算字串表达式值的类》 挺热闹!
如果从数据结构角度讨论思路应该是:
中缀表达式到后缀表达式的转换,要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式!
这段程序只支持 正数的 + - * / () ,还很不完善,负数 -X 只能通过 (0-X) 来表示!
代码不多150行,功能有限,但的确是 解析算术表达式及计算求值 的经典算法
当然还很不成熟! 权当复习一下 stack 的功能 LIFO 中缀表达式到后缀表达式
代码非常简单任何多余的类库都没用,可以移植到任何语言!
C# Code:
Java Code:
《动态计算字串表达式值的类》 挺热闹!
如果从数据结构角度讨论思路应该是:
中缀表达式到后缀表达式的转换,要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式!
这段程序只支持 正数的 + - * / () ,还很不完善,负数 -X 只能通过 (0-X) 来表示!
代码不多150行,功能有限,但的确是 解析算术表达式及计算求值 的经典算法
当然还很不成熟! 权当复习一下 stack 的功能 LIFO 中缀表达式到后缀表达式
代码非常简单任何多余的类库都没用,可以移植到任何语言!
C# Code:
//using System;
class Class1
{
public static void Main()
{
System.Console.WriteLine("Hello World!");
//中缀 => 后缀表达式
string s = "( 1.9 + (20 + 41) / (25 * 11) - 3 ) * 2"; //中缀; //中缀
string S = ""; //后缀
char[] Operators = new char[s.Length];
int Top = -1;
for (int i = 0; i < s.Length; i++)
{
char C = s[i];
switch (C)
{
case ' ' : //忽略空格
break;
case '+' : //操作符
case '-' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '*' : //忽略空格
case '/' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
if (c == '+' || c == '-')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '(' :
Operators[++Top] = C;
S += " ";
break;
case ')' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
break;
}
else
{
S = S + c;
}
}
S += " ";
break;
default :
S = S + C;
break;
}
}
while (Top >= 0)
{
S = S + Operators[Top--]; //pop Operator
}
System.Console.WriteLine(S); //后缀
//后缀表达式计算
double[] Operands = new double[S.Length];
double x, y, v;
Top = - 1;
string Operand = "";
for (int i = 0; i < S.Length; i++)
{
char c = S[i];
if ((c >= '0' && c <= '9') || c == '.')
{
Operand += c;
}
if ((c == ' ' || i == S.Length - 1) && Operand != "") //Update
{
Operands[++Top] = System.Convert.ToDouble(Operand) ; //push Operands
Operand = "";
}
if (c == '+' || c == '-' || c == '*' || c == '/')
{
if ((Operand != ""))
{
Operands[++Top] = System.Convert.ToDouble(Operand) ; //push Operands
Operand = "";
}
y = Operands[Top--]; //pop 双目运算符的第二操作数 (后进先出)注意操作数顺序对除法的影响
x = Operands[Top--]; //pop 双目运算符的第一操作数
switch (c)
{
case '+' :
v = x + y;
break;
case '-' :
v = x - y;
break;
case '*' :
v = x * y;
break;
case '/' :
v = x / y; // 第一操作数 / 第二操作数 注意操作数顺序对除法的影响
break;
default :
v = 0;
break;
}
Operands[++Top] = v; //push 中间结果再次入栈
}
}
v = Operands[Top--]; //pop 最终结果
System.Console.WriteLine(v);
System.Console.ReadLine();
}
}
class Class1
{
public static void Main()
{
System.Console.WriteLine("Hello World!");
//中缀 => 后缀表达式
string s = "( 1.9 + (20 + 41) / (25 * 11) - 3 ) * 2"; //中缀; //中缀
string S = ""; //后缀
char[] Operators = new char[s.Length];
int Top = -1;
for (int i = 0; i < s.Length; i++)
{
char C = s[i];
switch (C)
{
case ' ' : //忽略空格
break;
case '+' : //操作符
case '-' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '*' : //忽略空格
case '/' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
if (c == '+' || c == '-')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '(' :
Operators[++Top] = C;
S += " ";
break;
case ')' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
break;
}
else
{
S = S + c;
}
}
S += " ";
break;
default :
S = S + C;
break;
}
}
while (Top >= 0)
{
S = S + Operators[Top--]; //pop Operator
}
System.Console.WriteLine(S); //后缀
//后缀表达式计算
double[] Operands = new double[S.Length];
double x, y, v;
Top = - 1;
string Operand = "";
for (int i = 0; i < S.Length; i++)
{
char c = S[i];
if ((c >= '0' && c <= '9') || c == '.')
{
Operand += c;
}
if ((c == ' ' || i == S.Length - 1) && Operand != "") //Update
{
Operands[++Top] = System.Convert.ToDouble(Operand) ; //push Operands
Operand = "";
}
if (c == '+' || c == '-' || c == '*' || c == '/')
{
if ((Operand != ""))
{
Operands[++Top] = System.Convert.ToDouble(Operand) ; //push Operands
Operand = "";
}
y = Operands[Top--]; //pop 双目运算符的第二操作数 (后进先出)注意操作数顺序对除法的影响
x = Operands[Top--]; //pop 双目运算符的第一操作数
switch (c)
{
case '+' :
v = x + y;
break;
case '-' :
v = x - y;
break;
case '*' :
v = x * y;
break;
case '/' :
v = x / y; // 第一操作数 / 第二操作数 注意操作数顺序对除法的影响
break;
default :
v = 0;
break;
}
Operands[++Top] = v; //push 中间结果再次入栈
}
}
v = Operands[Top--]; //pop 最终结果
System.Console.WriteLine(v);
System.Console.ReadLine();
}
}
Java Code:
class Class1
{
public static void main(String[] args)
{
System.out.println("Hello World!");
//中缀 => 后缀表达式
String s = "( 1.9 + (20 + 41) / (25 * 11) - 3 ) * 2"; //中缀
String S = ""; //后缀
char[] Operators = new char[s.length()];
int Top = -1;
for (int i = 0; i < s.length(); i++)
{
char C = s.charAt(i);
switch(C)
{
case ' ' :
break;
case '+' : //操作符
case '-' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '*' : //操作符
case '/' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
if (c == '+' || c == '-')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '(' : //操作符
Operators[++Top] = C;
S += " ";
break;
case ')' : //操作符
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
break;
}
else
{
S = S + c;
}
}
S += " ";
break;
default : //操作数
S = S + C;
break;
}
}
while (Top >= 0)
{
S = S + Operators[Top--]; //pop Operator
}
System.out.println(S); //后缀
//后缀表达式计算
double[] Operands = new double[S.length()];
double x, y, v;
Top = - 1;
String Operand = "";
for (int i = 0; i < S.length(); i++)
{
char c = S.charAt(i);
if ((c >= '0' && c <= '9') || c == '.')
{
Operand += c;
}
if ((c == ' ' || i == S.length() - 1) && Operand != "") //Update
{
Operands[++Top] = java.lang.Double.parseDouble(Operand) ; //push Operands
Operand = "";
}
if (c == '+' || c == '-' || c == '*' || c == '/')
{
if ((Operand != ""))
{
Operands[++Top] = java.lang.Double.parseDouble(Operand) ; //push Operands
Operand = "";
}
y = Operands[Top--]; //pop 双目运算符的第二操作数 (后进先出)注意操作数顺序对除法的影响
x = Operands[Top--]; //pop 双目运算符的第一操作数
switch (c)
{
case '+' :
v = x + y;
break;
case '-' :
v = x - y;
break;
case '*' :
v = x * y;
break;
case '/' :
v = x / y; // 第一操作数 / 第二操作数 注意操作数顺序对除法的影响
break;
default :
v = 0;
break;
}
Operands[++Top] = v; //push 中间结果再次入栈
}
}
v = Operands[Top--]; //pop 最终结果
System.out.println(v);
}
}
{
public static void main(String[] args)
{
System.out.println("Hello World!");
//中缀 => 后缀表达式
String s = "( 1.9 + (20 + 41) / (25 * 11) - 3 ) * 2"; //中缀
String S = ""; //后缀
char[] Operators = new char[s.length()];
int Top = -1;
for (int i = 0; i < s.length(); i++)
{
char C = s.charAt(i);
switch(C)
{
case ' ' :
break;
case '+' : //操作符
case '-' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '*' : //操作符
case '/' :
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
if (c == '+' || c == '-')
{
Operators[++Top] = c; //push Operator
break;
}
else
{
S = S + c;
}
}
}
Operators[++Top] = C; //push Operator
S += " ";
break;
case '(' : //操作符
Operators[++Top] = C;
S += " ";
break;
case ')' : //操作符
while (Top >= 0) //栈不为空时
{
char c = Operators[Top--]; //pop Operator
if (c == '(')
{
break;
}
else
{
S = S + c;
}
}
S += " ";
break;
default : //操作数
S = S + C;
break;
}
}
while (Top >= 0)
{
S = S + Operators[Top--]; //pop Operator
}
System.out.println(S); //后缀
//后缀表达式计算
double[] Operands = new double[S.length()];
double x, y, v;
Top = - 1;
String Operand = "";
for (int i = 0; i < S.length(); i++)
{
char c = S.charAt(i);
if ((c >= '0' && c <= '9') || c == '.')
{
Operand += c;
}
if ((c == ' ' || i == S.length() - 1) && Operand != "") //Update
{
Operands[++Top] = java.lang.Double.parseDouble(Operand) ; //push Operands
Operand = "";
}
if (c == '+' || c == '-' || c == '*' || c == '/')
{
if ((Operand != ""))
{
Operands[++Top] = java.lang.Double.parseDouble(Operand) ; //push Operands
Operand = "";
}
y = Operands[Top--]; //pop 双目运算符的第二操作数 (后进先出)注意操作数顺序对除法的影响
x = Operands[Top--]; //pop 双目运算符的第一操作数
switch (c)
{
case '+' :
v = x + y;
break;
case '-' :
v = x - y;
break;
case '*' :
v = x * y;
break;
case '/' :
v = x / y; // 第一操作数 / 第二操作数 注意操作数顺序对除法的影响
break;
default :
v = 0;
break;
}
Operands[++Top] = v; //push 中间结果再次入栈
}
}
v = Operands[Top--]; //pop 最终结果
System.out.println(v);
}
}