栈操作表达式的解析和运算

来源:互联网 发布:sqlserver 视图 编辑:程序博客网 时间:2024/06/07 01:02

package stack;

import java.util.Scanner;

public class Expression_Pattern
{
 int num,sign,curNum=0,curSign=0;
 String stackNum[],stackSign[];
  String str1[];
  public static void main(String[] args)
{
 Expression_Pattern ep=new Expression_Pattern();
  Scanner sc=new Scanner(System.in);
  while(sc.hasNext())
   {
   ep.setExpression(sc.next());
   System.out.println(ep.value());
   }
 
 
}
  public double value()
  {
   if(str1[1]==null)return -1;
    int i=0,j,right=0;
   double first,two;
    String sign;
  while(str1[i]!=null)
  {
   //判断是否是合法字符
   if(!isOperation(str1[i]))return -1;
   //如果是数字,数字后面不能是(和数字,该数字入栈
   if(str1[i].matches("\\d+"))
    {
    if(str1[i+1]!=null&&(str1[i+1].equals("(")||str1[i+1].matches("\\d+")))return -1;
    pushNum(str1[i]);
    i++;
    continue;
    }
   else
    //如果是“(”,“(”后面不能是“)”,并且不能以“(”为结尾,该“(”入栈
    if(str1[i].equals("("))
    {
    if(str1[i+1]==null||str1[i+1].matches("\\D")&&!str1[i+1].equals("("))return -1;
    pushSign(str1[i]);
    }
   else
    
    if(str1[i].equals(")"))
    {
     
         //“)”后面不能是“(”和数字
      if(str1[i+1]!=null&&(str1[i+1].equals("(")||str1[i+1].matches("\\d+")||curSign==0))return -1;
      //如果是“)”,则判断“)”的前一个字符是否是数字,二前第二个是“(”,如(8),如果是这种情况则返回-1
      if(i<2||(str1[i-1].matches("\\d+")&&str1[i-2].equals("(")))return -1;
      //如果运算符栈中为空(即没有“(”与该“)”匹配)则返回-1
      if(curSign==0) return -1;
      //取出运算符栈中的栈顶运算符,如果是“(”,则什么都不做,加入下回循环
      sign=popSign();
      if(sign.equals("("))
       {
       i++;
       continue;
       }
      //当运算符栈不为空并且取出来的不是“(”,则继续进行运算
      while(!sign.equals("("))
      {
       two=Double.parseDouble(popNum());
       first=Double.parseDouble(popNum());
       if(sign.equals("*"))first=first*two;
       else
       if(sign.equals("/"))first=first/two;
       else
        if(sign.equals("+"))first=first+two;
        else if(sign.equals("-"))
         first=first-two;
        else return -1;
      pushNum(first+"");
      //如果运算符栈中为空(即没有“(”与该“)”匹配)则返回-1
      if(curSign==0) return -1;
      sign=popSign();
      //如果运算符栈中为空并且刚刚取出的字符不是“(”(即没有“(”与该“)”匹配)则返回-1
      if(curSign==0&&!sign.equals("("))
       return -1;
      }
      
    }
   else
   {

    //如果是“+”,'/','+','-'等运算符,则运算符不能是第一位和最后一位,并且运算符后面不能跟‘)’
      if(i==0||str1[i+1]==null||str1[i+1].matches("\\D")&&!str1[i+1].equals("("))return -1;
     else
     {
      //如果运算符栈中还没有元素,则该运算符入栈
      if(curSign==0)
      {
       pushSign(str1[i]);
       i++;
       continue;
      }
      else
       {
      sign=peekSign();
      //如果运算符栈的栈顶元素是“(”或‘)’则该运算符入栈
      if(sign.equals("(")||sign.equals(")"))
       {
       pushSign(str1[i]);
       i++;
       continue;
       }
      //运算符栈的栈顶元素与该运算符进行优先级比较,如果该运算符优先级高,则进行运算
      if(compareSign(sign,str1[i])==-1)
      {
       if(str1[i+1].equals("("))
        {
        pushSign(str1[i]);
        i++;
        continue;
        }
       j=++i;
       first=Double.parseDouble(popNum());
          two=Double.parseDouble(str1[j]);
       if(str1[i-1].equals("*"))first=first*two;
       else if(str1[i-1].equals("/"))
        first=first/two;
       else return -1;
       pushNum(first+"");
       
      }
      else
      {
      //运算符栈的栈顶元素与该运算符进行优先级比较,如果该运算符优先级低,则取出运算符栈的栈顶运算符进行运算
       while(compareSign(sign,str1[i])==1)
       {
       sign=popSign();
       two=Double.parseDouble(popNum());
       first=Double.parseDouble(popNum());
       if(sign.equals("*"))first=first*two;
       else
        if(sign.equals("/"))first=first/two;
        else
         if(sign.equals("+"))first=first+two;
         else if(sign.equals("-"))
          first=first-two;
         else return -1;
       pushNum(first+"");
       if(curSign>0)
       sign=peekSign();
       else break;
       }
       pushSign(str1[i]);
      }
       }
     }
     
   }
   i++;
    
  }
  //System.out.println(curSign+"================");
  //如果运算符栈中还有元素,则还要对栈运算符进行运算
  if(curSign!=0)
  {
   if(curNum<2)return -1;
   int t=0;
   while(curSign>0)
   {
   if(curNum<2)return -1;
     two=Double.parseDouble(popNum());
     first=Double.parseDouble(popNum());
     sign=popSign();
     if(sign.equals("*"))first=first*two;
   else
    if(sign.equals("/"))first=first/two;
    else
     if(sign.equals("+"))first=first+two;
     else if(sign.equals("-"))
      first=first-two;
     else if(sign.equals(")"))t++;
          else if(sign.equals("("))t--;
     pushNum(first+"");
   }
   if(t!=0)return -1;
   
  }
  return Double.parseDouble(popNum());
  }
  //把字符串表达式解析出放到str1数组中
  public void setExpression(String express)
  {
   int loc=0,new_loc=0,str_first=0;
   String s=express;
   //以非数字作为分隔符,把字符串s中的数字放到str字符串数组中
   String str[]=s.split("\\D+");
   if(str.length!=0&&str[0].length()==0){loc=1;str_first=1;}
    str1=new String[s.length()+1];
  for(int i=0;i<s.length();i++)
  {
   //把字符串数组str中的数字和s中的符号按顺序放到str1中
   if(s.substring(i, i+1).matches("\\D"))
   {
    if(i>0&&s.substring(i-1, i).matches("\\d"))
    str1[new_loc++]=str[loc++];
    str1[new_loc++]=s.substring(i, i+1);
   }
  }
  //把str中剩下的字符串复制到str1中
  while(loc<str.length)
  {
   str1[new_loc++]=str[loc++];
  }
  for(String str3:str1)
  {
   //System.out.println(str3);
  }
  //设置数字栈的长度
  num=str.length;
  //设置长度为num的数字栈
  stackNum=new String[num+1];
  //设置非数字栈的长度
  sign=s.length()-num;
  //设置长度为sign的非数字栈
  stackSign=new String[sign+1];
  
  
  }
  //出栈
  public String popNum()
  {
  // System.out.println("pop"+(curNum-1)+"         "+stackNum[curNum-1]);
   return stackNum[--curNum];
 
  }
  public String popSign()
  {
   //System.out.println("------------SignPop"+(curSign-1)+"         "+stackSign[curSign-1]);
   return stackSign[--curSign];
  }
  public void pushNum(String str)
  {
 
   stackNum[curNum++]=str;
  // System.out.println("push"+curNum+"      "+stackNum[curNum-1]);
  }
  //入栈
  public void pushSign(String str)
  {
 
   stackSign[curSign++]=str;
  // System.out.println("------------Signpush"+curSign+"   "+stackSign[curSign-1]);
  }
  public String peekNum()
  {
   return stackNum[curNum-1];
  }
  //查看栈顶元素
  public String peekSign()
  {
   return stackSign[curSign-1];
  }
  //进行运算符优先级比较
  public int compareSign(String str1,String str2)
  {
   if(str1.equals("(")||str1.equals(")")||str2.equals("(")||str2.equals(")"))return 0;
   if(str1.equals("*")||str1.equals("/"))
   return 1;
   else if(str2.equals("*")||str2.equals("/"))return -1;
        else return 1;
 
  }
  //判断当前字符是否是数字或是否是四则运算符*,/,+,-中的一种,预即判断是否合法字符
  public boolean isOperation(String str)
  {
   if(str.matches("\\D"))
    if(str.equals("*")||str.equals("/")||str.equals("+")||str.equals("-")||str.equals("(")||str.equals(")"))
     return true;
    else return false;
   else return true;
  }
}

 

0 0
原创粉丝点击