Java实现四则运算表达式.docx

上传人:b****0 文档编号:9933014 上传时间:2023-05-22 格式:DOCX 页数:18 大小:18.94KB
下载 相关 举报
Java实现四则运算表达式.docx_第1页
第1页 / 共18页
Java实现四则运算表达式.docx_第2页
第2页 / 共18页
Java实现四则运算表达式.docx_第3页
第3页 / 共18页
Java实现四则运算表达式.docx_第4页
第4页 / 共18页
Java实现四则运算表达式.docx_第5页
第5页 / 共18页
Java实现四则运算表达式.docx_第6页
第6页 / 共18页
Java实现四则运算表达式.docx_第7页
第7页 / 共18页
Java实现四则运算表达式.docx_第8页
第8页 / 共18页
Java实现四则运算表达式.docx_第9页
第9页 / 共18页
Java实现四则运算表达式.docx_第10页
第10页 / 共18页
Java实现四则运算表达式.docx_第11页
第11页 / 共18页
Java实现四则运算表达式.docx_第12页
第12页 / 共18页
Java实现四则运算表达式.docx_第13页
第13页 / 共18页
Java实现四则运算表达式.docx_第14页
第14页 / 共18页
Java实现四则运算表达式.docx_第15页
第15页 / 共18页
Java实现四则运算表达式.docx_第16页
第16页 / 共18页
Java实现四则运算表达式.docx_第17页
第17页 / 共18页
Java实现四则运算表达式.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Java实现四则运算表达式.docx

《Java实现四则运算表达式.docx》由会员分享,可在线阅读,更多相关《Java实现四则运算表达式.docx(18页珍藏版)》请在冰点文库上搜索。

Java实现四则运算表达式.docx

Java实现四则运算表达式

四则混合运算的算符优先算法Java实现

 

它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。

它们之间的区别在于运算符相对与操作数的位置不同:

前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。

举例:

(3+4)×5-6就是中缀表达式-×+3456前缀表达式34+5×6-后缀表达式中缀表达式(中缀记法)中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。

中缀表达式是人们常用的算术表示方法。

虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。

对计算机来说,计算前缀或后缀表达式的值非常简单。

前缀表达式(前缀记法、波兰式)

前缀表达式的运算符位于操作数之前。

前缀表达式的计算机求值:

从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素op次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

例如前缀表达式“-×+3456”:

(1)从右至左扫描,将6、5、4、3压入堆栈;

(2)遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;

(3)接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;

(4)最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

可以看出,用计算机计算前缀表达式的值是很容易的。

将中缀表达式转换为前缀表达式:

遵循以下步骤:

(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

5

数字,直接入栈

-

5

-

S1为空,运算符直接入栈

5

-)

右括号直接入栈

4

54

-)

数字直接入栈

×

54

-)×

S1栈顶是右括号,直接入栈

54

-)×)

右括号直接入栈

3

543

-)×)

数字

+

543

-)×)+

S1栈顶是右括号,直接入栈

2

5432

-)×)+

数字

5432+

-)×

左括号,弹出运算符直至遇到右括号

5432+×

-

同上

+

5432+×

-+

优先级与-相同,入栈

1

5432+×1

-+

数字

到达最左端

5432+×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=35,将35入栈;

(5)将6入栈;

(6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

将中缀表达式转换为后缀表达式:

与转换为前缀表达式相似,遵循以下步骤:

(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(栈底->栈顶)

说明

1

1

数字,直接入栈

+

1

+

S1为空,运算符直接入栈

1

+(

左括号,直接入栈

1

+((

同上

2

12

+((

数字

+

12

+((+

S1栈顶为左括号,运算符直接入栈

3

123

+((+

数字

123+

+(

右括号,弹出运算符直至遇到左括号

×

123+

+(×

S1栈顶为左括号,运算符直接入栈

4

123+4

+(×

数字

123+4×

+

右括号,弹出运算符直至遇到左括号

-

123+4×+

-

-与+优先级相同,因此弹出+,再压入-

5

123+4×+5

-

数字

到达最右端

123+4×+5-

S1中剩余的运算符

因此结果为“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){

System.out.println("\ninputerror,notanumber.");

}catch(IllegalArgumentExceptione){

System.out.println("\ninputerror:

"+e.getMessage());

}catch(Exceptione){

System.out.println("\ninputerror,invalidexpression.");

}

System.out.print("ReversePolishNotation(RPN):

");

try{

toReversePolishNotation(input);

}catch(NumberFormatExceptione){

System.out.println("\ninputerror,notanumber.");

}catch(IllegalArgumentExceptione){

System.out.println("\ninputerror:

"+e.getMessage());

}catch(Exceptione){

System.out.println("\ninputerror,invalidexpression.");

}

System.out.println("inputanewexpression:

");

input=scanner.nextLine();

}

System.out.println("programexits");

}

/**

*parsetheexpression,andcalculateit.

*paraminput

*throwsIllegalArgumentException

*throwsNumberFormatException

*/

privatestaticvoidtoPolishNotation(Stringinput)

throwsIllegalArgumentException,NumberFormatException{

intlen=input.length();

charc,tempChar;

Stacks1=newStack();

Stacks2=newStack();

Stackexpression=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()!

=')'

&&prioritypare(c,s1.peek())<0){

expression.push(s1.peek());

s2.push(calc(s2.pop(),s2.pop(),s1.pop()));

}

s1.push(c);

}elseif(c==')'){

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')'.");

}

}

}elseif(c==''){

//ignore

}else{

thrownewIllegalArgumentException(

"wrongcharacter'"+c+"'");

}

}

while(!

s1.isEmpty()){

tempChar=s1.pop();

expression.push(tempChar);

s2.push(calc(s2.pop(),s2.pop(),tempChar));

}

while(!

expression.isEmpty()){

System.out.print(expression.pop()+"");

}

doubleresult=s2.pop();

if(!

s2.isEmpty())

thrownewIllegalArgumentException("inputisawrongexpression.");

System.out.println();

if((int)result==result)

System.out.println("theresultis"+(int)result);

else

System.out.println("theresultis"+result);

}

/**

*parsetheexpression,andcalculateit.

*paraminput

*throwsIllegalArgumentException

*throwsNumberFormatException

*/

privatestaticvoidtoReversePolishNotation(Stringinput)

throwsIllegalArgumentException,NumberFormatException{

intlen=input.length();

charc,tempChar;

Stacks1=newStack();

Stacks2=newStack();

doublenumber;

intlastIndex=-1;

for(inti=0;i

c=input.charAt(i);

if(Character.isDigit(c)||c=='.'){

lastIndex=readDouble(input,i);

number=Double.parseDouble(input.substring(i,lastIndex));

s2.push(number);

i=lastIndex-1;

if((int)number==number)

System.out.print((int)number+"");

else

System.out.print(number+"");

}elseif(isOperator(c)){

while(!

s1.isEmpty()

&&s1.peek()!

='('

&&prioritypare(c,s1.peek())<=0){

System.out.print(s1.peek()+"");

doublenum1=s2.pop();

doublenum2=s2.pop();

s2.push(calc(num2,num1,s1.pop()));

}

s1.push(c);

}elseif(c=='('){

s1.push(c);

}elseif(c==')'){

while((tempChar=s1.pop())!

='('){

System.out.print(tempChar+"");

doublenum1=s2.pop();

doublenum2=s2.pop();

s2.push(calc(num2,num1,tempChar));

if(s1.isEmpty()){

thrownewIllegalArgumentException(

"bracketdosen'tmatch,missingleftbracket'('.");

}

}

}elseif(c==''){

//ignore

}else{

thrownewIllegalArgumentException(

"wrongcharacter'"+c+"'");

}

}

while(!

s1.isEmpty()){

tempChar=s1.pop();

System.out.print(tempChar+"");

doublenum1=s2.pop();

doublenum2=s2.pop();

s2.push(calc(num2,num1,tempChar));

}

doubleresult=s2.pop();

if(!

s2.isEmpty())

thrownewIllegalArgumentException("inputisawrongexpression.");

System.out.println();

if((int)result==result)

System.out.println("theresultis"+(int)result);

else

System.out.println("theresultis"+result);

}

/**

*calculatethetwonumberwiththeoperation.

*paramnum1

*paramnum2

*paramop

*return

*throwsIllegalArgumentException

*/

privatestaticdoublecalc(doublenum1,doublenum2,charop)

throwsIllegalArgumentException{

switch(op){

case'+':

returnnum1+num2;

case'-':

returnnum1-num2;

case'*':

returnnum1*num2;

case'/':

if(num2==0)thrownewIllegalArgumentException("divisorcan'tbe0.");

returnnum1/num2;

default:

return0;//willnevercatchuphere

}

}

/**

*parethetwooperations'priority.

*paramc

*parampeek

*return

*/

privatestaticintprioritypare(charop1,charop2){

switch(op1){

case'+':

case'-':

return(op2=='*'||op2=='/'?

-1:

0);

case'*':

case'/':

return(op2=='+'||op2=='-'?

1:

0);

}

return1;

}

/**

*readthenextnumber(reverse)

*paraminput

*paramstart

*return

*throwsIllegalArgumentException

*/

privatestaticintreadDoubleReverse(Stringinput,intstart)

throwsIllegalArgumentException{

intdotIndex=-1;

charc;

for

展开阅读全文
相关搜索
资源标签


copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2