两种表达式
中缀 | 后缀 |
---|---|
A+B | AB+ |
A+B*C | ABC*+ |
(A+B)*C-D | AB+C * D- |
重要性质
- 中缀表达式1+2 * 4和后缀表达式124 * +中,数字顺序是一样的,只有算术符号顺序不一样
- 只需一个栈就可以把中缀转后缀,利用栈把表达式中的运算符次序从中序改为后序。栈中只存放运算符和左括号,由于后缀表达式中不存在括号,所以输出的时候将不输出括号。
算法
a)创建一个栈
b)while(字符串未结束)
if(t是操作数) 输出t
else if(t是右括号)
出栈并输出该符号,直至一个匹配的左括号出栈(但左括号不输出)
else
当栈非空且t的优先级不大于栈顶元素时,出栈并输出
t入栈
c)当栈非空的时候,出栈并输出所有字符
Java版本实现
//中缀转后缀算法
static String MinddleTurnToBack(String curString) {
LLStack stack = new LLStack();
String result = "" ;
System.out.print("中缀表达式转换为后缀表达式:");
for(int i = 0; i < curString.length(); i++) {
char t = curString.charAt(i);
if(isNumber(t)) {
//数字直接输出
System.out.print(t);
result = result + t;
}else if((t == ')' || t == ']' || t == '}')) {
//当栈顶不是‘(’时,出栈并输出
while(!stack.isEmpty() && stack.top() != '(' && stack.top() != '[' && stack.top() != '{'){
result += stack.top();
System.out.print((char)stack.pop());
}
//直到栈顶是‘(’
if (!stack.isEmpty())
stack.pop();
}else {//操作符或‘(’
//当栈非空且t的优先级不大于栈顶元素时,出栈并输出然后t入栈
while(!stack.isEmpty() && isPriority((char)stack.top(), t)) {
result += stack.top();
System.out.print((char)stack.pop());
}
stack.push(t);
}
}
while(!stack.isEmpty()) {
result += stack.top();
System.out.print((char)stack.pop());
}
System.out.println();
return result;
}
栈的实现
package com.wuyi.notecode;
class LLNode{
private char data;
private LLNode next = null;
public LLNode(char d){
data = d;
}
public int getData() {
return data;
}
public void setData(char data) {
this.data = data;
}
public LLNode getNext() {
return next;
}
public void setNext(LLNode next) {
this.next = next;
}
}
public class LLStack {
private LLNode head;
boolean isEmpty() {
return head == null;
}
int size() {
int count = 1;
LLNode cur = head;
if(isEmpty()) return 0;
while(cur.getNext() !=null ) {
cur = cur.getNext();
count++;
}
return count;
}
int top() {
if(isEmpty())
new Exception("栈空");
return head.getData();
}
void push(char d) {
if(isEmpty()) {
head =new LLNode(d);
}else {
LLNode node = new LLNode(d);
node.setNext(head);
head = node;
}
}
int pop() {
if(isEmpty())
new Exception("栈空");
LLNode del = head;
head = head.getNext();
return del.getData();
}
void display() {
if(isEmpty()) {
System.out.println("栈空");
}else {
LLNode cur = head;
System.out.print("栈内元素:");
while(cur != null) {
System.out.print(cur.getData() + "->");
cur = cur.getNext();
}
System.out.println();
}
}
void deleteStack() {
head = null;
}
public static void main(String[] args) {
LLStack ls = new LLStack();
ls.push('2');
ls.push('3');
System.out.println("栈顶元素:" + ls.top());
ls.display();
System.out.println("移除栈顶元素:" + ls.pop());
ls.push('5');
System.out.println("删除整个栈");
ls.deleteStack();
ls.display();
}
}
完整测试代码
import java.util.Scanner;
public class StackApplication {
//括号匹配算法
static boolean isMatch(LLStack stack,String curString) {
//字符处理
for(int i = 0; i < curString.length(); i++) {
char ch = curString.charAt(i);
switch(ch) {
case '(' :
stack.push(ch);
break;
case '[' :
stack.push(ch);
break;
case '{' :
stack.push(ch);
break;
case ')' :
if(stack.isEmpty() || stack.top() != '(' ) {
System.out.println("括号匹配失败");
return false;
}else {
stack.pop();
}
break;
case ']' :
if(stack.isEmpty() || stack.top() != '[' ) {
System.out.println("括号匹配失败");
return false;
}else {
stack.pop();
}
break;
case '}' :
if(stack.isEmpty() || stack.top() != '{' ) {
System.out.println("括号匹配失败");
return false;
}else {
stack.pop();
}
break;
}
}
//字符处理后栈非空
if(!stack.isEmpty()) {
System.out.println("括号匹配失败");
return false;
}
//System.out.println("括号匹配成功");
return true;
}
//算术符号优先级算法
static boolean isPriority(char top, char t) {
/*if(a == '(' || a == '[' || a == '{') return true;
if(b == '(' || b == '[' || b == '{' ) return true;
if(b == '*' || b == '/' || b == '%')
return false;
else if(a == '*' || a == '/' || a == '%')
return true;
else if(b == '+' || b == '-' )
return false;
else return true;
*/
if((t == '+' || t == '-') && (top == '*' || top == '/'))
return true;
return false;
}
static boolean isNumber(char t){
//这里为了测试一下字母,所以把字母也加进来了
if (t >= '0' && t <= '9' || t >= 'a' && t <= 'z' || t >= 'A' && t <= 'Z' )
return true;
return false;
}
//中缀转后缀算法
static String MinddleTurnToBack(String curString) {
LLStack stack = new LLStack();
String result = "" ;
System.out.print("中缀表达式转换为后缀表达式:");
for(int i = 0; i < curString.length(); i++) {
char t = curString.charAt(i);
if(isNumber(t)) {
//数字直接输出
System.out.print(t);
result = result + t;
}else if((t == ')' || t == ']' || t == '}')) {
//当栈顶不是‘(’时,出栈并输出
while(!stack.isEmpty() && stack.top() != '(' && stack.top() != '[' && stack.top() != '{'){
result += stack.top();
System.out.print((char)stack.pop());
}
//直到栈顶是‘(’
if (!stack.isEmpty())
stack.pop();
}else {//操作符或‘(’
//当栈非空且t的优先级不大于栈顶元素时,出栈并输出然后t入栈
while(!stack.isEmpty() && isPriority((char)stack.top(), t)) {
result += stack.top();
System.out.print((char)stack.pop());
}
stack.push(t);
}
}
while(!stack.isEmpty()) {
result += stack.top();
System.out.print((char)stack.pop());
}
System.out.println();
return result;
}
public static void main(String[] args) {
LLStack stack = new LLStack();
Scanner scanner = new Scanner(System.in);
String curString = "";
while(true) {
System.out.println("请输入表达式:");
curString = scanner.next();
if(isMatch(stack,curString))
MinddleTurnToBack(curString);
}
}
}