/**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]);
}
}
}