Java实现四则运算表达式Word文档格式.docx
《Java实现四则运算表达式Word文档格式.docx》由会员分享,可在线阅读,更多相关《Java实现四则运算表达式Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
将中缀表达式转换为前缀表达式:
遵循以下步骤:
(1)初始化两个栈:
运算符栈S1和储存中间结果的栈S2;
(2)从右至左扫描中缀表达式;
(3)遇到操作数时,将其压入S2;
(4)遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1)如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
(4-2)否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
(4-3)否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5)遇到括号时:
(5-1)如果是右括号“)”,则直接压入S1;
(5-2)如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;
(6)重复步骤
(2)至(5),直到表达式的最左边;
(7)将S1中剩余的运算符依次弹出并压入S2;
(8)依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
例如,将中缀表达式“1+((2+3)×
4)-5”转换为前缀表达式的过程如下:
扫描到的元素
S2(栈底->
栈顶)
S1(栈底->
说明
5
空
数字,直接入栈
-
S1为空,运算符直接入栈
)
-)
右括号直接入栈
4
54
数字直接入栈
×
-)×
S1栈顶是右括号,直接入栈
)
3
543
数字
+
)+
2
5432
(
5432+
左括号,弹出运算符直至遇到右括号
5432+×
同上
-+
优先级与-相同,入栈
1
1
到达最左端
1+-
S1中剩余的运算符
因此结果为“-+1×
+2345”。
后缀表达式(后缀记法、逆波兰式)
后缀表达式与前缀表达式类似,只是运算符位于操作数之后。
后缀表达式的计算机求值:
与前缀表达式类似,只是顺序是从左至右:
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素op栈顶元素),并将结果入栈;
重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
例如后缀表达式“34+5×
6-”:
(1)从左至右扫描,将3和4压入堆栈;
(2)遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈;
(3)将5入栈;
(4)接下来是×
运算符,因此弹出5和7,计算出7×
(5)将6入栈;
(6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果。
将中缀表达式转换为后缀表达式:
与转换为前缀表达式相似,遵循以下步骤:
(2)从左至右扫描中缀表达式;
(4-1)如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2)否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(5-1)如果是左括号“(”,则直接压入S1;
(5-2)如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6)重复步骤
(2)至(5),直到表达式的最右边;
(8)依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
4)-5”转换为后缀表达式的过程如下:
+(
左括号,直接入栈
+((
12
+((+
S1栈顶为左括号,运算符直接入栈
123
123+
右括号,弹出运算符直至遇到左括号
+(×
123+4
123+4×
+
-与+优先级相同,因此弹出+,再压入-
+5
到达最右端
+5-
因此结果为“123+4×
+5-”(注意需要逆序输出)。
编写Java程序将一个中缀表达式转换为前缀表达式和后缀表达式,并计算表达式的值。
其中的toPolishNotation()方法将中缀表达式转换为前缀表达式(波兰式)、toReversePolishNotation()方法则用于将中缀表达式转换为后缀表达式(逆波兰式):
注:
下面程序是为了说明上述概念而编写,做了简单的测试
packageqmk.simple_test;
importjava.util.Scanner;
importjava.util.Stack;
/**
*Exampleofconvertinganinfix-expressionto
*PolishNotation(PN)orReversePolishNotation(RPN).
*Writtenin2011-8-25
*@authorQiaoMingkui
*/
publicclassCalculator{
publicstaticfinalStringUSAGE="
==usage==\n"
+"
inputtheexpressions,andthentheprogram"
willcalculatethemandshowtheresult.\n"
input'
bye'
toexit.\n"
;
/**
*@paramargs
publicstaticvoidmain(String[]args){
System.out.println(USAGE);
Scannerscanner=newScanner(System.in);
Stringinput="
"
finalStringCLOSE_MARK="
bye"
System.out.println("
inputanexpression:
);
input=scanner.nextLine();
while(input.length()!
=0
&
&
!
CLOSE_MARK.equals((input))){
System.out.print("
PolishNotation(PN):
try{
toPolishNotation(input);
}catch(NumberFormatExceptione){
\ninputerror,notanumber."
}catch(IllegalArgumentExceptione){
\ninputerror:
+e.getMessage());
}catch(Exceptione){
\ninputerror,invalidexpression."
}
ReversePolishNotation(RPN):
toReversePolishNotation(input);
inputanewexpression:
programexits"
*parsetheexpression,andcalculateit.
*@paraminput
*@throwsIllegalArgumentException
*@throwsNumberFormatException
privatestaticvoidtoPolishNotation(Stringinput)
throwsIllegalArgumentException,NumberFormatException{
intlen=input.length();
charc,tempChar;
Stack<
Character>
s1=newStack<
();
Double>
s2=newStack<
Object>
expression=newStack<
doublenumber;
intlastIndex=-1;
for(inti=len-1;
i>
=0;
--i){
c=input.charAt(i);
if(Character.isDigit(c)){
lastIndex=readDoubleReverse(input,i);
number=Double.parseDouble(input.substring(lastIndex,i+1));
s2.push(number);
i=lastIndex;
if((int)number==number)
expression.push((int)number);
else
expression.push(number);
}elseif(isOperator(c)){
while(!
s1.isEmpty()
s1.peek()!
='
)'
priorityCompare(c,s1.peek())<
0){
expression.push(s1.peek());
s2.push(calc(s2.pop(),s2.pop(),s1.pop()));
s1.push(c);
}elseif(c=='
){
('
while((tempChar=s1.pop())!
expression.push(tempChar);
s2.push(calc(s2.pop(),s2.pop(),tempChar));
if(s1.isEmpty()){
thrownewIllegalArgumentException(
"
bracketdosen'
tmatch,missingrightbracket'
."
'
//ignore
}else{
wrongcharacter'
+c+"
'
s1.isEmpty()){
tempChar=s1.pop();
expression.isEmpty()){
System.out.print(expression.pop()+"
doubleresult=s2.pop();
if(!
s2.isEmpty())
thrownewIllegalArgumentException("
inputisawrongexpression."
System.out.println();
if((int)result==result)
theresultis"
+(int)result);
+result);
*parsetheexpression,andcalculateit.
privatestaticvoidtoReversePolishNotation(Stringinput)
for(inti=0;
i<
len;
++i){
if(Character.isDigit(c)||c=='
.'
lastIndex=readDouble(input,i);
number=Double.parseDouble(input.substring(i,lastIndex));
i=lastIndex-1;
System.out.print((int)number+"
System.out.print(number+"
=0){
System.out.print(s1.peek()+"
doublenum1=s2.pop();
doublenum2=s2.pop();
s2.push(calc(num2,num1,s1.pop()));
System.out.print(tempChar+"
s2.push(calc(num2,num1,tempChar));
tmatch,missingleftbracket'
*calculatethetwonumberwiththeoperation.
*@paramnum1
*@paramnum2
*@paramop
*@return
privatestaticdoublecalc(doublenum1,doublenum2,charop)
throwsIllegalArgumentException{
switch(op){
case'
+'
:
returnnum1+num2;
-'
returnnum1-num2;
*'
returnnum1*num2;
/'
if(num2==0)thrownewIllegalArgumentException("
divisorcan'
tbe0."
returnnum1/num2;
default:
return0;
//willnevercatchuphere
*comparethetwooperations'
priority.
*@paramc
*@parampeek
privatestaticintpriorityCompare(charop1,charop2){
switch(op1){
return(op2=='
||op2=='
?
-1:
0);
1:
return1;
*readthenextnumber(reverse)
*@paramstart
privatestaticintreadDoubleReverse(Stringinput,intstart)
throwsIllegalArgumentEx