您的位置:首页 > 其它

算数表达式求值(中缀表达式转后缀表达式并求值)

2016-04-10 15:57 597 查看
中缀表达式转后缀表达式的规则:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时栈顶的运算符为"(",则将这个运算符也压入栈中)
6.最终将栈中的元素依次出栈,输出

具体代码实现:

第一步:中缀表达式转后缀表达式

package data.struct.algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

//定义栈,用于存放转换过程中的操作符
class StackFix {
// 栈的大小
private int maxSize;
// 数组模拟栈
private char stackArr[];
// 栈顶指针
private int top;

// 构造函数初始化栈
public StackFix(int s) {
maxSize = s;
stackArr = new char[maxSize];
top = -1;
}

// 进栈
public void push(char value) {
stackArr[++top] = value;
}

// 出栈
public char pop() {
return stackArr[top--];
}

// 显示栈顶元素
public char peek() {
return stackArr[top];
}

// 判断栈是否为空
public boolean isEmpty() {
return top == -1;
}
}

// 转换类
class InTranstoPost {
private StackFix theStackFix;
private String input;
private String output = "";

// 初始化
public InTranstoPost(String in) {
input = in;
int stackSize = input.length();
theStackFix = new StackFix(stackSize);
}

// 主要转换功能函数
public String doTran() {
for (int j = 0; j < input.length(); j++) {
// 获取一个输入字符串的一个字符
char ch = input.charAt(j);
switch (ch) {

case '+':
case '-':
// 如果字符为'+'或者'-',若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数1为运算符的优先级
gotOper(ch, 1);
break;
case '*':
case '/':
// 如果字符为'*'或者'/',若栈空,则直接让该字符进栈,否则,弹出栈顶元素进行判断,参数2为运算符的优先级
gotOper(ch, 2);
break;
case '(':
// 如果字符为'(',则压入栈中
theStackFix.push(ch);
break;
case ')':
// 如果字符为')',则弹出栈顶元素,如果栈顶元素为'(',则结束循环,输出转换结果,否则依次弹出栈顶元素并输出,
// 直到碰到'('
gotRbracket(ch);
break;
default:
// 字符为操作数,不入栈,直接输出
output = output + ch;
break;
}
}
// 判断输入的字符串的每一个字符的循环结束,依次弹出栈中的元素,并输出
while (!theStackFix.isEmpty()) {
output = output + theStackFix.pop();
}
return output;
}

// 该函数用于字符为')'时的相应操作
public void gotRbracket(char ch) {
while (!theStackFix.isEmpty()) {
char chx = theStackFix.pop();
if (chx == '(') {
break;
} else {
output = output + chx;
}
}
}

// 非')'字符的其他操作符的处理
public void gotOper(char opThis, int prec1) {
while (!theStackFix.isEmpty()) {
char opTop = theStackFix.pop();
if (opTop == '(') {
theStackFix.push(opTop);
break;
} else {
int prec2;
if (opTop == '+' || opTop == '-') {
prec2 = 1;
} else {
prec2 = 2;
}
if (prec2 < prec1) {
theStackFix.push(opTop);
break;
} else {
output = output + opTop;
}
}
}
// 栈空,字符直接压入栈中
theStackFix.push(opThis);
}
}

// 主函数
public class InfixToPostFix {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {

// 定义两个字符串,一个接收键盘输入,一个用于代表转换后的字符串
String input, output;
while (true) {
System.out.println("Enter a InFix:");
System.out.flush();
// getString()函数,从键盘获取输入的中缀表达式字符串
input = getString();
// 输入的字符串为空,结束判断
if (input.equals("")) {
break;
}
// 进行转换
InTranstoPost tran = new InTranstoPost(input);
output = tran.doTran();
System.out.println("Thr Postfix is " + output);
}
}

// 键盘获取输入的方式,常用做法
public static String getString() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bufr = new BufferedReader(isr);
String s = bufr.readLine();
return s;
}
}


第二步:后缀表达式求值

在这里,我的程序没有使用上一步获取的转换后的字符串,而是继续接收用户额输入,如果使用上一步的结果,则程序会变得更简单一些

求值的步骤:

(1)设置一个栈,开始时,栈为空,然后从左到右扫描后缀表达式

(2)若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈

(3)直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果,弹出栈即可得到结果。

具体代码实现:

package data.struct.algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

class Stackfix2 {
private int maxSize;
private int stackArr[];
private int top;

public Stackfix2(int maxSize) {
this.maxSize = maxSize;
stackArr = new int[maxSize];
top = -1;
}

// 进栈
public void push(int value) {
stackArr[++top] = value;
}

// 出栈
public int pop() {
return stackArr[top--];
}

// 显示栈顶元素
public int peek() {
return stackArr[top];
}

// 判断栈是否为空
public boolean isEmpty() {
return top == -1;
}

public boolean isFull() {
return top == maxSize - 1;
}
}

class Postfix {
private Stackfix2 theStackfix2;
private String input;

public Postfix(String in) {
input = in;
}

public int doCalculate() {
int num1;
int num2;
int inresult;
char ch;
int j;
theStackfix2 = new Stackfix2(20);
for (j = 0; j < input.length(); j++) {
ch = input.charAt(j);
// 如果字符为整数,则进行类型强制转换,并压入栈中
if (ch >= '0' && ch <= '9') {
theStackfix2.push((int) (ch - '0'));
} else {
// 测试用例最最关键的位置,考虑计算过程中的操作数的位置
// 先弹出栈的元素是第二个操作数,后弹出栈的是第一个操作数
num2 = theStackfix2.pop();
num1 = theStackfix2.pop();
switch (ch) {
case '+':
inresult = num1 + num2;
break;
case '-':
inresult = num1 - num2;
break;
case '*':
inresult = num1 * num2;
break;
case '/':
inresult = num1 / num2;
break;
default:
inresult = 0;
break;
}
theStackfix2.push(inresult);
}
}
return theStackfix2.pop();
}
}

public class PostfixValue {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {

while (true) {
System.out.println("Enter a Postfix:");
System.out.flush();
String input;
int result;
input = getString();
Postfix parse = new Postfix(input);
result = parse.doCalculate();
System.out.println("Postfix求值的结果是:" + result);
}
}

public static String getString() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bufr = new BufferedReader(isr);
return bufr.readLine();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: