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;
}
}