您的位置:首页 > 编程语言

接上篇文章的中缀与后缀的代码实现

2013-04-07 16:58 316 查看
代码分为3部分,其实只要两部分的,就是一个测试类和一个计算类。下面看代码:

package lesson.arry;

import java.util.Stack;

public class Calculate {

public int calSuffix(String []str){  //计算后缀表达式的值
MyStack sk=new MyStack();
int second,first;
for(String tmp :str){
switch(tmp){
case "+":
second=sk.pop();
first=sk.pop();
sk.push(first+second);
break;
case "-":
second=sk.pop();
first=sk.pop();
sk.push(first-second);
break;
case "*":
second=sk.pop();
first=sk.pop();
sk.push(first*second);
break;
case "/":
second=sk.pop();
first=sk.pop();
sk.push(first/second);
break;
default:
Integer j=Integer.parseInt(tmp);
sk.push(j);
break;
}
}
return sk.pop();
}
public void infixToSuffix(String []source,String []destination){  //中缀表达式变换为后缀表达式
int index=0;
Stack<String> sk=new Stack<String>();
for(String tmp:source){
switch(tmp){
case "+":
case "-": //因为+ -它们的优先级是一样的,可以放一起处理
if(!sk.empty() && sk.peek()=="(")  //只有左括号优先级比+号低    加号和减号优先级一样
sk.push(tmp);
else{
while(!sk.empty() && sk.peek()!="("){
destination[index++]=sk.pop();
}
sk.push(tmp);
}
break;
case "*":
case "/":
if(!sk.empty() && sk.peek()!="/" && sk.peek()!="*")  //只有左括号优先级比+号低    加号和减号优先级一样
sk.push(tmp);
else{
while(!sk.empty() && (sk.peek()=="/" || sk.peek()=="*")){
destination[index++]=sk.pop();
}
sk.push(tmp);
}
break;
case "(": //所有的中括号还是大括号都可以换为小括号,所以没必要再去考虑其他复杂的括号
sk.push(tmp);
break;
case ")":
while(!sk.empty() && sk.peek()!="("){
destination[index++]=sk.pop();
}
sk.pop();  //去除左括号
break;
default:
destination[index++]=tmp;
break;
}
//			for(String temp:sk)  //测试用
//				System.out.print(temp);
//			System.out.println();
//			for(String temp:destination)
//				System.out.print(temp);
//			System.out.println();
}  //结束for循环
while(!sk.empty()){
destination[index++]=sk.pop();
}
}

public int calInfix(String[]str){  //计算中缀表达式
int count=0;
for(String temp:str){
if(temp.equals("(")){ //含有括号时后缀表达式要变短
count++;
}
}
String[]destination=new String[str.length-2*count];
infixToSuffix(str, destination);//中缀表达式变为后缀表达式

System.out.print("后缀表达式为:");
for(String temp:destination)  //查看后缀表达式
System.out.print(temp);
System.out.println();

return calSuffix(destination);  //调用后缀表达式
}
}

上面已经说了,只需要两个类的,为了更加的熟悉栈,所以自己写了一个栈,没java自带的好,勉强能用吧。代码如下:

package lesson.arry;

public class MyStack {
public int[] datas;
public int index=-1;
public MyStack(){
this(10);  //必须放在最前面
}
public MyStack(int size){
datas=new int[size];
}
public void push(int data){
if(index>=datas.length-1){
int[] tempArry=new int[datas.length+5];
System.arraycopy(datas, 0, tempArry, 0, datas.length);
datas=tempArry;
//			System.gc();  //通知垃圾回收器工作
}
index++;
datas[index]=data;
}

public int pop(){
if(index<=-1)
return 0;
return datas[index--];
}
public boolean isEmpty(){
return index<=-1;
}

public int peek(){
if(index<=-1)
return 0;
return datas[index];
}
/*
public static void main(String args[]){
MyStack ms=new MyStack();
Calculate ca=new Calculate();
//		for(int i=0;i<30;i++){
//			ms.push((int)(Math.random()*100+1));
//		}
//		while(!ms.isEmpty()){
//			System.out.println(ms.pop());
//		}
String []str=new String[]{"1","2","3","+","4","*","+"};
String []str2=new String[]{"1","+","(","2","+","3",")","*","4"};
try{
System.out.println(ca.calSuffix(str));
System.out.println(ca.calInfix(str2));
}catch(Exception e){
e.printStackTrace();
}
}
*/
}


两个类都定义完了,接下来就是随便写个类来测试一下:

package lesson.arry;

public class Test {
public static void main(String[] args) {
Calculate calculate = new Calculate();

String []str=new String[]{"1","2","3","+","4","*","+"};
String []str2=new String[]{"1","+",
"(","2","+","3",")","*","4"}; //1+(2+3)*4
String []str3=new String[]{"2","+","(","10","+","4","*","2",")",
"/","2","-","1"}; //2+(10+4*2)/2-1
try{
System.out.print("直接使用后缀表达式结果为: ");
System.out.println(calculate.calSuffix(str));
System.out.println(calculate.calInfix(str2)); //测试1
System.out.println(calculate.calInfix(str3)); //测试2
}catch(Exception e){
e.printStackTrace();
}
}
}


结果都是正确的,想验证的可以拷下去跑一跑,代码肯定有好多的bug,好多地方还没有考虑,比如输入字符要报错啊什么的,这个以后大家再改吧,现在只是简单的提供一下自己的算法,欢迎补充。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: