计算带括号的四则运算表达式

/**Node.java
 * 字符栈的节点类
 */
package 四则运算带括号;

public class Node {
	private char charElem;
	private int intElem;
	private Node next;
	public Node(){//初始化
		this.next=null;
		this.charElem=' ';
	}
	public void setCharElem(char c){//赋值
		this.charElem=c;
	}
	public void setIntElem(int i){
		this.intElem=i;
	}
	public char getCharElem(){//返回节点值
		return this.charElem;
	}
	public int getIntElem(){
		return this.intElem;
	}
	public void setNext(Node n){//赋值
		this.next=n;
	}
	public Node getNext(){//返回下一个栈节点
		return this.next;
	}
	//一定要保证节点不为null,存放数字时返回true,存放字符时返回false
	public boolean getIntOrChar(){
		if(this.getCharElem()==' ')
			return true;
		else
			return false;
	}
}
/* Stack.java
 * char型栈,将中缀表达式转化为后缀表达式
 */

package 四则运算带括号;

public class Stack {
	private Node top;
	private int stackLength;//栈中元素个数
	public Stack(){//初始化时为空栈
		this.top=null;
		this.stackLength=0;
	}
	public Node getTop(){
		return this.top;
	}
	//入栈操作
	public void pushCharElemToStack(char c){
		if(this.top==null){
			Node newNode=new Node();
			newNode.setCharElem(c);
			top=newNode;
			top.setNext(null);
			this.stackLength=1;
		}
		else{
			Node newNode=new Node();
			newNode.setCharElem(c);
			Node temp=top;
			newNode.setNext(temp);
			top=newNode;
			this.stackLength++;
		}
	}
	public void pushIntElemToStack(int i){
		if(this.top==null){
			Node newNode=new Node();
			newNode.setIntElem(i);
			top=newNode;
			top.setNext(null);
			this.stackLength++;
		}
		else{
			Node newNode=new Node();
			newNode.setIntElem(i);
			Node temp=top;
			newNode.setNext(temp);
			top=newNode;
			this.stackLength++;
		}
	}
	//出栈操作
	public char popCharFromStack(){
		char c=this.getTop().getCharElem();//保存原先的栈顶元素
		top=top.getNext();//新的栈顶节点,,之前的由java自动释放
		this.stackLength--;
		return c;
	}
	public int popIntFromStack(){
		int i=this.getTop().getIntElem();
		top=top.getNext();
		this.stackLength--;
		return i;
	}
	public void popTop(){
		Node temp=top;
		top=temp.getNext();
		this.stackLength--;
	}
	//打印整个栈,从左到右是栈底元素到栈顶元素
	public void printStack(){
		if(top==null)
			System.out.println("the stack is enpty.");
		else{
			Node temp=null;
			int k=this.stackLength;
			while(k>0){
				for(int i=k;i>0;i--){
					if(i==k)
						temp=this.getTop();
					else
						temp=temp.getNext();
				}
				//节点中存放的是数字
				if(temp.getCharElem()==' ')
					System.out.print(temp.getIntElem()+" ");
				else//节点中存放的是字符
					System.out.print(temp.getCharElem()+" ");
				k=k-1;
			}
			System.out.println();
		}
	}
}
/*Cacul.java
 *计算,将中缀表达式转换成后缀表达:
 *转换规则:
 *  1)若取出的字符是数字,则分析出完整的运算数,该运算数直接送入S2栈
 *  2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符
 *    优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈
 *    顶运算符弹出,压入入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算
 *    符优先级,则将该运算符压入S1栈
    3)若取出的字符是“(”,则直接压入S1栈栈顶
    4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈
              依次送入S2栈,此时抛弃“(”
    5) 重复上面的1~4步,直至处理完所有的输入字符  
    6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次压入S2栈
 */

package 四则运算带括号;

import java.util.Scanner;

public class Cacul {
	public String inputString;//要输入的表达式,可能含有空格哟吼吼,

	public static void main(String[] args) {
		// TODO 自动生成的方法存�?
		Cacul cacul=new Cacul();
		cacul.getNewString();
		Stack S1=new Stack();
		Stack S2=new Stack();
		Stack S3=new Stack();
		//检查输入是否规范(以“#”开头和结尾
		if(check(cacul.inputString)&&checkType(cacul.inputString)){
			cacul.operation(cacul.inputString,S1,S2);
			
			System.out.print("S1:");
			S1.printStack();
			System.out.print("S2:");
			S2.printStack();
			System.out.print("S3:");
			S3.printStack();
			
			//此时S2中存放的后缀表达式应该进行一下倒序,,因此可以将元素从S2中弹出压入S3栈
			char s;
			while(S2.getTop()!=null){//注意下面两条语句的逻辑哟吼吼,,,
				if(S2.getTop().getCharElem()==' ')//如果节点存的是数字
					S3.pushIntElemToStack(S2.popIntFromStack());
				else
					S3.pushCharElemToStack(S2.popCharFromStack());
			}
			
			System.out.print("S1:");
			S1.printStack();
			System.out.print("S2:");
			S2.printStack();
			System.out.print("S3:");
			S3.printStack();
			
			int intNum1,intNum2,total1;
			while(S3.getTop()!=null){
				s=S3.getTop().getCharElem();
				if(s==' '){//如果从S3中弹出的是数字,直接压入栈S2
					S2.pushIntElemToStack(S3.popIntFromStack());	
				}
				else{
					switch(s){//要注意的是先取出的元素是减数,加数,乘数,除数?
					case '+':
						intNum1=S2.popIntFromStack();
						intNum2=S2.popIntFromStack();
						total1=intNum2+intNum1;
						S2.pushIntElemToStack(total1);
						break;
					case '-':
						intNum1=S2.popIntFromStack();
						intNum2=S2.popIntFromStack();
						total1=intNum2-intNum1;
						S2.pushIntElemToStack(total1);
						break;
					case '*':
						intNum1=S2.popIntFromStack();
						intNum2=S2.popIntFromStack();
						total1=intNum2*intNum1;
						S2.pushIntElemToStack(total1);
						break;
					case '/':
						intNum1=S2.popIntFromStack();
						intNum2=S2.popIntFromStack();
						total1=intNum2/intNum1;
						S2.pushIntElemToStack(total1);
						break;
					}
					S3.popTop();
				}
			}
			int sum=S2.getTop().getIntElem();
			System.out.println(sum);
		}
		
	}
	
	public void getNewString(){
		System.out.println("请输入一个包含加减乘除的表达式(注意要以#开头和结尾):");
		String newString;
		Scanner scanner=new Scanner(System.in);//创建扫描器
		newString=scanner.nextLine();
		scanner.close();//关闭扫描器
		this.inputString=newString.replaceAll(" ", "");//去除字符串中的空格
	}
	public static boolean check(String s){
		char c[]=s.toCharArray();
		while(c[0]=='#'&&c[c.length-1]=='#')
			return true;
		return false;
	}
	//检查字符串中是否只有 ( ) + - * / # 以及数字这些类型字符
	public static boolean checkType(String s){
		char newArray[]=s.toCharArray();
		boolean b=true;
		for(int i=0;i<newArray.length;i++){
			if(newArray[i]=='#')
				continue;
			if(newArray[i]>=40&&newArray[i]<=43)
				continue;
			if(newArray[i]>=47&&newArray[i]<=57)
				continue;
			if(newArray[i]=='-')
				continue;
			b=false;
			if(b==false)
				break;
		}
		return b;
	}
	//若c为运算符,则返回false,否则,返回true
	public boolean JudgeType(char c){//判断每个字符c是运算符还是数字
		if(c<48||c>57)
			return false;
		return true;
	}
	//判断运算符优先级op1为栈顶元素,op2为读入的元素
	public char JudgeOp(char op1,char op2){
		switch(op1){
		case '#':
			return '>';
		case '(':
			switch(op2){
			case '+':
			case '-':
			case '*':
			case '/':
			case '(':
				return '>';
			}
		case '+':
			switch(op2){
			case '*':
			case '/':
			case '(':
				return '>';
			case '+':
			case '-':
				return '=';
			}
		case '-':
			switch(op2){
			case '*':
			case '/':
			case '(':
				return '>';
			case '+':
			case '-':
				return '=';
			}
		case '*':
			switch(op2){
			case '(':
				return '>';
			case '*':
			case '/':
				return '=';
			case '+':
			case '-':
				return '<';
			}
		case '/':
			switch(op2){
			case '(':
				return '>';
			case '*':
			case '/':
			case '+':
			case '-':
				return '<';
			}
		}
		return ' ';
	}
	//将表达式从中中缀转为后缀
	//k2中存放的就是最终的后缀表达式
	public void operation(String s,Stack k1,Stack k2){
		char newArray[]=s.toCharArray();
		
		Print(newArray);
		System.out.println();
		
		k1.pushCharElemToStack('#');//将‘#’压入栈S1
		
		System.out.print("S1:");
		k1.printStack();
		System.out.print("S2:");
		k2.printStack();
		
		int i=1;
		while(i<newArray.length-1){//newArray[length-1]='#'
			if(JudgeType(newArray[i])){//数字情况
				int j=i+1;//看下一位是否为数字
				int count=1;//统计这个完整的整型数字是几位数
				while(j<newArray.length-1&&JudgeType(newArray[j])){
					count++;
					j++;
				}
				int number=0;//最终得到的
				int m;
				for(int k=count;k>=1;k--){
					int num=1;
					for(int l=1;l<k;l++){
						num=num*10;
					}
					m=newArray[i+count-k]-'0';
					number=number+m*num;
				}
				//将number压入栈S2
				k2.pushIntElemToStack(number);
				i=i+count;
				
				System.out.print("S1:");
				k1.printStack();
				System.out.print("S2:");
				k2.printStack();
			}
			else{//字符情况
				char c1=k1.getTop().getCharElem();
				char c2=newArray[i];
				char result=JudgeOp(c1,c2);//将S1栈顶元素和要读入S1或S2的元素比较优先级
				//将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈
				//依次送入S2栈,此时抛弃“(”
				if(c2==')'){
					Node tempNode=k1.getTop();
					int count=0;
					while(tempNode.getCharElem()!='('){
						count++;
						tempNode=tempNode.getNext();
					}
					for(int ki=1;ki<=count;ki++){
						k2.pushCharElemToStack(k1.popCharFromStack());
					}
					k1.popTop();//删去‘(’
					i=i+1;
					
					System.out.print("S1:");
					k1.printStack();
					System.out.print("S2:");
					k2.printStack();
				}
				
				else if(result=='>'){//若c2优先级高于c1,将c2压入栈S1
					k1.pushCharElemToStack(c2);
					i=i+1;
					
					System.out.print("S1:");
					k1.printStack();
					System.out.print("S2:");
					k2.printStack();
				}
				/* c2运算符优先级小于等于c1运算符优先级
				 * 将从S1中栈顶开始优先级大于等于c2的元素依次弹出,压入S2栈顶
				 * 将该运算符压入S1栈
				 */
				else{
					char tempChar;
					tempChar=k1.getTop().getCharElem();
					char r=JudgeOp(tempChar,c2);
					while(r=='='||r=='<'){
						//压入S2
						k2.pushCharElemToStack(tempChar);
						k1.popTop();//弹出S1
						tempChar=k1.getTop().getCharElem();
						r=JudgeOp(tempChar,c2);
					}
					//将c2压入S1
					k1.pushCharElemToStack(c2);
					i=i+1;
					
					System.out.print("S1:");
					k1.printStack();
					System.out.print("S2:");
					k2.printStack();
				}
			}
		}
		//将栈S1中的剩余符号弹出,压入到S2
		while(k1.getTop()!=null){
			k2.pushCharElemToStack(k1.popCharFromStack());
		}
	}
	public void Print(char[] newArray){
		System.out.println("the array is");
		for(int i=0;i<newArray.length;i++){
			System.out.print(newArray[i]);
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值