数据结构前缀表达式后缀表达式报告正文

数据结构前缀表达式后缀表达式报告正文
数据结构前缀表达式后缀表达式报告正文

一、设计思想

计算表达式有两种方法:

第一种方法:直接计算表达式:

具体实现思想如下:

通过get()函数,输入所要计算的表达式。调用calculate(char ch[])函数,然后

先建立两个栈,一个数值栈,一个操作符栈,同时将两个栈初始化为空,利用while

循环获取表达式字符,并对表达式字符进行判断,如果是空格则直接跳过,如果是

0到9的数字或者小数点‘.’,则利用trans()函数把数字转化为浮点型的数,然后

在将浮点型的数值压栈,如果是操作符,则先判断操作符栈是否为空,如果为空,

则操作符直接入栈,如果不为空,则先判断是不是右括号,如果是,则将栈顶元素

出栈,并将数值栈中的两个元素出栈,进行相应的运算,然后把结果入栈,直到遇

到左括号为止,并且把左括号出栈,如果不为左括号,则比较所扫描元素与栈顶元

素的优先级,如果所扫描元素的优先级高于栈顶元素的优先级,则把所扫描元素直

接入栈,如果所扫描元素的优先级低于栈顶元素的优先级,则先判断栈顶是不是左

括号,如果是左括号则直接入栈,如果不是左括号,则将栈顶元素出栈,并将数值

栈中的两元素出栈,进行相应的运算,然后把结果放入数值栈中,知道所扫描元素

的优先级高于栈顶元素的优先级为止,如果扫到了表达式的结尾,即扫到了‘\0’,则判断此时操作符栈是否为空,如果不为空,则把操作符栈中的操作符出栈,并将

数值栈中的两个数值出栈进行相应的运算,然后压入数值栈,知道操作符栈为空为

止。最后将最后结果从数值栈中出栈,并返回此结果。此时表达式就计算出了最后

结果。

第二种方法:先把中缀表达式转化为后缀表达式,然后在对后缀表达式进行计算。

具体实现思想如下:

1、中缀表达式转为后缀表达式:在主函数中通过gets()函数获得要进行计算的表达式,

然后调用中缀转换函数transform(char exp[],char tem[]),然后先定义一个操作

符栈,并初始化为空,利用while循环获得表达式字符,并进行判断,如果是空格

则直接跳过,如果不是空格,则判断是不是0到9的数字或者小数点‘.’,如果

是则把此数字字符赋给字符数组tem[],如果是操作符,则先判断操作符栈是不是

为空,如果为空,则操作符直接压入栈中,如果不是为空,则判断是不是右括号,

如果是右括号,则将栈顶元素出栈,赋给字符数组,tem[],知道遇到左括号为止,如果不是左括号,则比较所扫描元素与栈顶元素的优先级,如果所扫描元素的优先

级高于栈顶元素的优先级,则直接入栈,如果所扫描元素的优先级小于栈顶元素的

优先级,则判断栈顶元素是不是左括号,如果是左括号,则所扫描元素直接入栈,

如果不是左括号则将栈顶元素出栈并赋给字符数组tem[],知道遇到所扫描元素的

优先级高于栈顶元素的情况为止。如果扫到字符串结束标志,即‘\0’,则利用while

循环将操作符栈中的操作符全部出栈,并赋给字符数组tem[],然后将tem[]数组

返回。

2、后缀表达式计算:调用后缀表达式计算函数calculate(char ch[]),建立一个数值

栈,并初始化为空,然后利用while循环获得表达式字符,并进行判断,如果是数

字字符,则将数字字符利用trans()函数转化为浮点型的数字,并将转化后的数字

压入数值栈,如果是操作符,则从数值栈将两个数值出栈并进行相应的运算,然后

将计算结果压入数值栈,当扫到后缀表达式结尾的时候,将数值栈中的最后结果出

栈并返回,此时表达式就计算出了最后结果。

二、算法流程图

第一种算法:直接计算表达式,其流程图为:

图1 直接计算算法流程图

第二种算法:先中缀表达式转化为后缀表达式,然后在计算后缀表达式,其流程图为:

图2 中缀转后缀算法流程图

图3 后缀表达式计算算法流程图

三、源代码

下面给出的是用直接计算算法实现的程序的源代码:/* Note:Your choice is C IDE */

/*表达式直接运算*/

#include"stdio.h"

#include"stdlib.h"

#define Maxsize 100

/////////////////////////////////////////////////////

////定义操作符栈

typedef struct{/////定义操作符栈

char data[Maxsize];

int top;

}Stack;

void InitStack(Stack *S) /////用于初始化栈

{

S->top=-1;

}

int push(Stack *S,char op)//将一个新元素压入栈中

{

if(S->top==Maxsize-1) ///判断栈是否为空,并进行处理{

printf("\n stack is full");

return 0; /////如果栈满则返回0值}

S->top++;

S->data[S->top]=op; ////把元素压入栈顶

return 1;

}

char pop(Stack *S) /////定义出栈函数

{

if(S->top==-1) /////判断栈是否为空

{

printf("the stack is empty");

return 0;

}

return S->data[S->top--]; /////返回栈顶元素

}

////////////定义数值栈

typedef struct{////定义数值栈

double data1[Maxsize];

int top;

}ODStack;

void InitStack1(ODStack *S) //////初始化栈

{

S->top=-1;

}

int push1(ODStack *S,double OpNd)//将一个新元素压入栈中{

if(S->top==Maxsize-1) ///判断栈是否为空,并进行处理{

printf("\n stack is full");

return 0;

}

S->top++;

S->data1[S->top]=OpNd; /////把元素压入栈顶

return 1;

}

double pop1(ODStack *S) ///////出栈函数

{

if(S->top==-1) //////判断栈是否为空

{

printf("the stack is empty");

return 0;

}

return S->data1[S->top--]; /////返回栈顶元素

}

/////////定义优先级

int level(char oper)

{int lvl; /////定义记录优先级的变量switch(oper)

{

case'+': lvl=1;break;

case'-':lvl=1;break; ////定义…-?…+?的优先级

case'*':lvl=2;break;

case'/':lvl=2;break; ////定义…*?…、?的优先级

case'%':lvl=2;break; ////定义…%?的优先级

case'(':lvl=6;break;

case')':lvl=0;break; ////定义…(?…)?的优先级}

return lvl; //////返回操作符的优先级

}

int precede(char oper1,char oper2)////进行优先级比较

{

int result;

result=level(oper1)-level(oper2);

return result; ////返回优先级比较结果

}

void main()

{

double calculate(char ch[]);

char expression[Maxsize]; /////声明要使用的函数

printf("Attention!!!:the side of '%' must be intgral number\n");

printf("please input the expression :");

gets(expression); ////输入所要计算的算式

printf("the value after calculating the expression is: %.4f\n",calculate(expression));

//////输出计算结果

}

////////////////////////////////////////////////////

////////////定义计算表达式

double calculate(char ch[])

{double cal(double tem1,double tem2,char c);

//////////声明cal()函数

int i=0,k=0;

char transform[Maxsize],*s_t;////声明存放数值的字符数组

char tem;

double d1,d2,od1,od2,result;

Stack Optr; //////声明数值栈

ODStack Opnd; //////声明操作符栈

InitStack(&Optr); ///////初始化操作符栈

InitStack1(&Opnd); /////初始化数值栈

while(ch[i]!='\0') /////扫描后缀表达式

{

if(ch[i]==' ') ////跳过空格

{

i++;

}

if(ch[i]>='0'&&ch[i]<='9'||ch[i]=='.')///判断是不是数值

{

while(ch[i]>='0'&&ch[i]<='9'||ch[i]=='.')//将字符转化为浮点型

{

transform[k]=ch[i]; /////将数值字串的每一个字符赋给trans数组

k++;

i++;

}

transform[k]='\0'; ///以…\0?结尾存放数值串

k=0;

s_t=transform;

d1=atof(s_t); ////利用atof()函数将转为浮点型

push1(&Opnd,d1);

// printf("the top of the stack is:%f\n",Opnd.data1[Opnd.top]);

}

else/////对操作符进行操作

{

if(Optr.top==-1) ///判断站的状态,空则直接压入

{

push(&Optr,ch[i]); /////入栈

}

else

{

if(ch[i]==')') ///判断是不是')',对括号内的表达式进行运算

{

while( Optr.data[Optr.top]!='(')////以…)?为条件处理括号内的操作符

{

tem=pop(&Optr); /////栈顶元素出栈

od2=pop1(&Opnd); ////将符号右元素出栈

od1=pop1(&Opnd); ////将符号左元素出栈

d2=cal(od1,od2,tem); /////调用计算函数

push1(&Opnd,d2); ////将所得结果压入数值栈

}

pop(&Optr); ////(出栈

}

else///////对操作符进行处理

{

if(precede(ch[i],Optr.data[Optr.top])<=0&&Optr.top>=0) //栈顶元素大于所扫描元素的情况

{

while(precede(ch[i],Optr.data[Optr.top])<=0&&Optr.top!=-1)

{

if(Optr.data[Optr.top]=='(')/////如果是…(?直接进行操作符运算

break;

tem=pop(&Optr); ///栈顶元素出栈

od2=pop1(&Opnd); ////将符号右元素出栈

od1=pop1(&Opnd); ////将符号左元素出栈

d2=cal(od1,od2,tem);////调用计算函数

push1(&Opnd,d2); ///将所得结果压入栈中

}

push(&Optr,ch[i]); ////当栈顶元素优先级小于所扫描元素时,将元素入栈

}

if(precede(ch[i],Optr.data[ Optr.top])>0)///优先级大于栈顶元素的时候直接入栈

{

push(&Optr,ch[i]); /////入栈

}

}

}

i++; /////使i加1保证循环继续进行

}

}

//printf("ddddddd%c\n",Optr.data[Optr.top]);

while(Optr.top!=-1) ///将操作符栈中的操作符全部出栈并运算

{

tem=pop(&Optr); ///操作符出栈

od2=pop1(&Opnd); // 操作符右元素出栈

od1=pop1(&Opnd); //操作付左操作付出栈

d2=cal(od1,od2,tem);///调用计算函数

push1(&Opnd,d2); ////将所得结果入栈

}

result=pop1(&Opnd); ///将所得最后结果出栈

return(result); ///返回算式结果

}

///////////////////////////////////////////

////定义基本计算函数

double cal(double tem1,double tem2,char c)

{

double tem; //声明变量tem用以存放计算结果

switch(c)

{

case'+':tem=tem1+tem2; break;//加法

case'-':tem=tem1-tem2; break;///减法

case'/':tem=tem1/tem2; break;//除法

case'*':tem=tem1*tem2; break;//乘法

case'%':tem=(double)((int)tem1%(int)tem2);

}

return tem; ////返回计算结果

}‘

下面给出的是用中缀转后缀然后在计算算法实现的程序的源代码:/* Note:Your choice is C IDE */

/////后缀表达式计算

#include"stdio.h"

#include"stdlib.h"

#define Maxsize 100

#define addsize 20

/////////////////////////////////////////////////////

////定义操作符栈

typedef struct{//////////建立操作符栈

char data[Maxsize];

int top;

}Stack;

void InitStack(Stack *S) ///////////初始化栈

{

S->top=-1;

}

int push(Stack *S,char op) //将一个新元素压入栈中

{

if(S->top==Maxsize-1) ///判断栈是否为空,并进行处理{

printf("\n stack is full");

return 0;

}

S->top++;

S->data[S->top]=op; //////将元素op压入栈

return 1;

}

char pop(Stack *S) ///////////将栈顶元素出栈

{

if(S->top==-1) ////////////////////判断栈是否为空{

printf("the stack is empty");

return 0;

}

return S->data[S->top--]; /////不为空进行出栈操作

}

////////////定义数值栈

typedef struct{

double data1[Maxsize];

int top;

}ODStack;

void InitStack1(ODStack *S)

{

S->top=-1;

}

int push1(ODStack *S,double OpNd) //将一个新元素压入栈中

{

if(S->top==Maxsize-1) ///判断栈是否为空,并进行处理{

printf("\n stack is full");

return 0;

}

S->top++;

S->data1[S->top]=OpNd; //////////进行压栈操作

return 1;

}

double pop1(ODStack *S) ////将栈顶元素出栈

{

if(S->top==-1) ///////判断栈是否为空

{

printf("the stack is empty");

return 0;

}

return S->data1[S->top--]; ////////返回栈顶元素的值

}

/////////定义优先级

int level(char oper)

{int lvl;

switch(oper) ///////由switch选择函数来定义优先级

{

case'+': lvl=1;break;

case'-':lvl=1;break; //////定义“+”“-”的优先级

case'*':lvl=2;break;

case'/':lvl=2;break; //////定义“/”“*”的优先级

case'%':lvl=2;break; //////定义“%”的优先级

case'(':lvl=6;break;

case')':lvl=0;break; ///////定义括号的优先级

}

return lvl; /////返回操作符的优先级

}

int precede(char oper1,char oper2) /////优先级比较函数

{

int result;

result=level(oper1)-level(oper2);

return result; ////////////返回优先级比较结果

}

void main()

{

double calculate(char ch[]);

void transform(char exp[],char tem[]); ///////进行函数声明

char expression[Maxsize],temp[Maxsize];///////定义存放表达式的数组

printf("Attention!!!:the side of '%' must be integral number\n");

printf("please input the expression :");

gets(expression); //////表达式输入函数

transform(expression,temp); //////前缀转后缀函数调用

printf("the expression after changing is:%s\n",temp);////输出后缀表达式

printf("the value after calculating the expression is: %.4f\n",calculate(temp));///输出计算结果}

////////////////////////////////////////////////////////////////////

/////////定义前缀转后缀的函数

void transform(char exp[],char tem[])

{

int i=0,k=0;

Stack optr; //////定义操作符栈

InitStack(&optr); ///////初始化操作符栈

while(exp[i]!='\0') ////////对表达式进行扫描,以符号“\0”

{

if(exp[i]==' ') ///////判断字符是否为空格

{i++;

continue;

}

if(exp[i]>='0'&&exp[i]<='9'||exp[i]=='.')//////判断字符是否为0到9的数字或小数点

{

tem[k]=exp[i];

k++;

}

else///////////////////对字符进行操作

{

tem[k++]='#'; //////////////用做数字间的分隔符

if(optr.top==-1)

{

push(&optr,exp[i]);

}

else

{

if(exp[i]==')') //////////判断是否为“)”,并进行相应的操作

{

while(optr.data[optr.top]!='(')/////利用while循环来pop出栈顶元素,直到遇到“)”

{

tem[k]=pop(&optr);

k++;

}

pop(&optr); /////////使“(“出栈

}

else

{

if(precede(exp[i],optr.data[ optr.top])<=0)//对所扫描元素优先级小于栈顶元素的情况进行处理

{

while(precede(exp[i],optr.data[optr.top])<=0&&optr.top!=-1)

{

if(optr.data[optr.top]=='(') ////判断栈顶元素是否为“(”

break;

tem[k]=pop(&optr);

k++;

}

push(&optr,exp[i]); /////将所扫描元素压栈

}

if(precede(exp[i],optr.data[ optr.top])>0)////对优先级大于栈顶元素的情况进行处理,

{

push(&optr,exp[i]); /////将元素直接入栈

}

}

}

}

i++; /////保证循环继续进行,继续扫描下一个元素}

while(optr.top!=-1) /////将操作符栈中的元素全部出栈,以top等于-1为界

{

tem[k++]=pop(&optr);

}

tem[k]='\0'; //////使tem以字符串形势存在

}

////////////////////////////////////////////////////////////////////////////////////

/////////后缀表达式计算函数

double calculate(char ch[])

{

int i=0,k=0;

char transform[Maxsize],*st; /////声明存放数字字符的数组trans,以及指向他的指针

double d1,od1,od2,tem_r,result;

ODStack opnd; ////声明数值栈

InitStack1(&opnd); /////初始化数值栈

while(ch[i]!='\0') ///////对后缀表达式进行扫描,以…\0'为界

{if(ch[i]=='#') ///////判断数字之间的分隔符,

{

i++;

}

if(ch[i]>='0'&&ch[i]<='9'||ch[i]=='.')///////判断是否为数值

{

while(ch[i]>='0'&&ch[i]<='9'||ch[i]=='.')////一循环方式得到一个完整的数

{

transform[k]=ch[i]; ////把数字一字符形式存放在数组trans中

k++;

i++;

}

transform[k]='\0'; //////使字符以字符串的形式贮存

k=0;

st=transform;

d1=atof(st); //////利用atof()函数将字符型数组转化为浮点型的push1(&opnd,d1);

}

else

{

switch(ch[i]) ///////以c为入口,选择所要进行的运算

{

case'+':od2=pop1(&opnd); /////进行加法运算,并第二个数出栈

od1=pop1(&opnd); /////第一个数出栈

tem_r=od1+od2; /////进行加法运算

push1(&opnd,tem_r);/////将结果入栈

break;

case'-':od2=pop1(&opnd); //////进行减法运算,并第二个数出栈

od1=pop1(&opnd); ///////第一个数出栈

tem_r=od1-od2; //////进行减法出栈

push1(&opnd,tem_r);/////将结果入栈

break;

case'/':od2=pop1(&opnd); ////////进行除法运算,并第二个数出栈

od1=pop1(&opnd);////////第一个数出栈

tem_r=od1/od2; //////进行除法运算

push1(&opnd,tem_r);/////将结果入栈

break;

case'*':od2=pop1(&opnd);////////进行除法运算,第二个数出栈

od1=pop1(&opnd);///////第一个数出栈

tem_r=od1*od2; //////进行乘法运算

push1(&opnd,tem_r);/////将运算结果入栈

break;

case'%': od2=pop1(&opnd); //进行取余运算,第二个数出栈

od1=pop1(&opnd);///////第一个数出栈

tem_r=(double)((int)od1%(int)od2);////进行取余运算

push1(&opnd,tem_r);////将运算结果入栈

break;

}

i++; //////确保循环继续进行

}

}

result=pop1(&opnd); ////把运算结果出栈

return result; ///////返回运算结果

}

四、运行结果

图 4 直接运算运行结果图

图 5 中缀转后缀,后缀再运算运行结果图

五、遇到的问题及解决

这部分我主要遇到了如下两个问题,其内容与解决方法如下所列:

●在中缀表达式转后缀表达式时,循环条件思考不周全,具体描述如下:

在扫描表达式时,当所扫描字符是操作符时,开始检测栈顶为空这种情况,当栈不

为空时,要比较所扫描元素与栈顶元素的优先级,当栈顶优先级低的时候直接压栈,当所扫描元素的优先级小于栈顶元素优先级的时候,利用while循环使栈顶元素逐

个出栈,直到栈顶元素的优先级小于所扫描元素优先级,所以我就以如下表达式

precede(exp[i],optr.data[optr.top])<=0为条件写了while循环,但出现了死

循环的情况,运行结果如下图

图 6 中缀转后缀时错误结果图

解决方法如下:

当所扫描元素的优先级小于栈顶元素的优先级时,栈顶元素要逐个出栈,如果只考

虑precede(exp[i],optr.data[optr.top])<=0这个条件的话,栈顶元素确实会逐

个出栈,比如输入8-4*3这样的表达式不会出错,但如果输入8-4+3或者4*3-3

这种表达式时就会出错,原因是当表达式为后者时,栈顶元素会全部出栈,从而会

出现操作符栈为空的情况,当操作符栈为空的情况下,栈中没有数值可以作为实参

传递给优先级比较函数,所以此时就没有优先级比较这个必要了,但条件中没有体

现出这个限制条件,所以只要遇到操作符栈会为空的这种情况,此时优先级比较函

数的返回总是为小于0的情况,所以就会出现死循环,所以要添加一个必要的条件,正确条件为while(precede(exp[i],optr.data[optr.top])<=0&&optr.top!=-1)

此时就会输出正确的结果。

●在直接计算时函数形式参数的定义,与传递有错误,具体描述如下:

在直接计算时,定义了一个基本的计算函数,根据实参传来递的操作符的种类,来

进行相应的运算,我就参考出栈函数pop(),以一个数值栈类型的变量和字符型

的变量为形参,编写了基本计算函数cal(ODStack *S,char c),然后以栈名S对

传递过来的实参栈,进行相应的操作,但编译出现错误。

问题的解决方法如下:

在现在的知识范围内,不太了解以栈类型为形参的函数是如何进行传递的,是单向

值传递,还是像指针和数组那样,可以直接对实参里边的数值进行直接的更改,所

以避开了这一点,我以常用的类型的变量作为形参,所写函数如下

cal(double tem1,double tem2,char c),前两个参数是计算所需的两个数,C是

操作符,操作数直接从数值栈中出栈然后以实参形式传递给tem1,tem2.然后函数

体在进行的改变就解决了这个问题。

六、心得体会

常见前缀与后缀 英语 附加习题及答案

常见前缀与后缀1. 常见前缀

2. 名词后缀 3 . 形容词后缀

4. 动词后缀 5. 副词后缀 -ly是最常见的副词后缀, 可以附加在形容词后,构成与原形容词意义相同的副词。如:slowly 缓慢地happily高兴地truly 真实地wholly 全部地simply 纯粹地

练习 1. 动词、介词、冠词、物主代词等词后一般接名词或动名词, 如果所给单词是其它词类, 就要将其改为名词, 并注意名词数的变化。 (1)Do you know the ______ (deep) of the river? (2)His _____ (careful) resulted in the terrible accident (3)He is one of the ______ (science) who support this theory. 答案:(1) depth (2) carelessness (3) scientists 2. 动词、介词后一般接名词或动名词, 如果所给单词为动词,就要看该动词是否有名词形式,如果有名词形式,就用其名词形式;如果该动词没有名词形式,就用其动名词。如: (1)Please pay ________ (attend) to your handwriting. (2) His _______ (arrive) made the situation worse. (3)The teacher was angry at my _________ (come) late. 答案:(1) attention (2) arrival (3) coming 3. 动词前后、形容词前后可有副词。如果所需词为副词时, 还要考虑副词级的变化。如: (1)The boy ran ______ (quick) to school. (2)“What’s that?”Father shouted ______ (angry). (3)The little girl is ______(extreme)eager to know the result of the exam。 (4). He was very tired after doing this for a whole day, but he felt very happy since the crop did “grow”______ (height). 答案:(1) quickly (2) angrily (3) extremely (4) higher 4. 在名词前作定语,在系动词后做表语,以及作主语或宾语的补足语时,通常要用形容词如果所需词为形容词时, 还要考虑形容词级的变化。 (1) What’s the ________ (width) river in the world? (2) The _______ (strength) we become, the more modest we should be. 答案:(1) widest (2) stronger 5即时训练 单句填空:用所给单词的适当形式填空。 1. Mary was very ______ at the news, so she looked ______ at her husband, her eyes full of ______ (sad). 2. He ________football very well and he was one of the best ______ in yesterday’s football match. (play) 3. Look! How ________ Kate is laughing! She seems to be the ______ girl in the world (happy). 4. To our ______, the headmaster was very ______ with our report. (satisfy) 5. Edison was a great ________. During his life he had many ______. (invent) 6. I should ________ my task and make it ________ to finish it. (simple) 7. The boy having the ________ of being half starved ________, never to be seen again. (appear) 8. The police _____ the pot and ______ a plot against the President. (cover) 9. You are so _______ to help me. Thank you for your ________. (kindly)

后缀表达式求值

一、设计思想 首先,将中缀表达式转换为后缀表达式。转换算法思路:设中缀表达式已存入数组E[n];由于后缀表达式中操作数的次序与中缀表达式一致,故扫描到中缀表达式操作数时直接输出到B[n]即可;对于运算符,视其优先级别,优先级高的运算符先输出;设一存放运算符的栈s,先将s置空;依次扫描E[n]中各分量E[i]送x: 若x=“”(结束符),依次输出栈s中运算符,转换结束; 若x=操作数,直接输出x到B[n]中; 若x=‘)’,反复退栈输出栈s中子表达式运算符,直到栈顶符=‘(’,并退掉栈顶的‘(’; 若x=操作符,反复退栈输出栈s中运算符,直到栈顶符

三、源代码 下面给出的是用后缀表达式求值算法实现的程序的源代码: #include #include #define MaxSize 50 struct { char data[MaxSize]; int top; } op;//定义栈; struct { float data[MaxSize]; int top; } st; //中缀转换为后缀 void trans(char*exp,char*postexp) { int i=0; op.top=-1; while(*exp!='\0') { switch(*exp) { case'(': op.top++;op.data[op.top]=*exp; exp++;break; case')': while(op.data[op.top]!='(') { postexp[i++]=op.data[op.top]; op.top--; } op.top--;exp++;break; case'+': case'-': while(op.top!=-1&&op.data[op.top]!='(') { postexp[i++]=op.data[op.top]; op.top--; }

(完整版)常用前缀后缀

常用前缀后缀 一.表示否定的前缀 1.dis-加在名词、形容词,动词之前。 disadvantage(缺点)dishonorable(不光彩的)disagree(不同意) 2.in-加在形容词,名词之前 incorrect(不正确的),inability(无能,无力),inaccurate(不准确的) 3.im-加在字母m,b,p之前 impossible(不顺能的),impolite(不礼貌的),impudence(厚颜无耻) 4.il-加在以1开头的词前 illegal(非法的),illiterate(文盲的,无文化的)illogical(不合逻辑的) 5.ir-加在以r开头的词前 irregular(不稳定的),irresistable(不可抵抗的),irresolvable(不能分解的,不能解决的) 6.un-加在名词,形容词,副词之前 unfinished(未完成的)undoubted(无疑的)unemployment(失业) 7.non-加在形容词,名词前 non-existence(不存在),non-essential(不主要的),non-electrical(非电的) 8.mis-加在动词、名词之前 misunderstand(误解),misjudge(误判),misleading(误导),misfortune(不幸) 9.de-加在名词,形容词之前 demobilize(遣散;使…复员) decolor (脱色, 漂白) 10.anti-加在名词、形容词之前 anti-Japanese(抗日战争),anti-social(厌恶社会的,反社会的),antidite(解毒药) 11.counter-加在名词、动词前 counterattack(反攻,反击),counteract(抵抗,阻碍)counterrevolution(反革命) 二.表示“前before”的前缀 1.pre- preconception(成见),pre-exsiting(先于……而存在的),pre-selection(选举前的) preface(前言) 2.ante- anteroom(前室,接待室),antecessor(先行者,先驱者) 3.fore- forehaed(前额),foreground(前景),foreman(工头,领班),foresee(预见,先见),foretell(预言) 4.pro- programme(计划),prologue(序幕) 5.ex- ex-president(前任总统)ex-wife(前妻) 三.表示“后-post”的前缀 1.post- post-war(战后),post-position(后置词),postmeridian(下午) 四.表示“低”、“下”的前缀 1.hypo- hypocrisy(伪善,虚伪),hypothesis(假设),pypocholoride(次氯酸盐) 2.Infra- infra-red(红外线),infrahuman(低于人类的),infrasonic(亚声的,次声的) 3.sub- sub-editou(副编辑),sub-way(地铁),sub-conscious(下意识的),submarine(海下的),subtropical(亚热带的),subtitle(副标题)

最常见的前缀和后缀

英语中的派生词的构成主要有三种:合成(由两个或两个以上的单词合成的单词);派生(指一个词根加上前缀或后缀构成的单词);转化(一种词性转化成另一种或几种词性的单词)。本文重点通过对前缀和后缀的剖析解读派生词的意义和特点。 先看下表: 一、前缀 1. dis- 表示意义相反,主要用在动词之前,间或用于名词或形容词前。如: appear (v.出现) → disappear (v.消失), 再如: dislike不喜欢 discover 发现 disobey不遵从 disbelieve 不相信 dishonest(adj.)不诚实的 disadvantage (n.) 不利条件,缺点 2. in-, im-, un-, il-, ir-用在形容词前,表示否定意义。如: indirect 间接的 incorrect 不正确的 inactive 不活动的

impossible 不可能的 unable 不能的 unhealthy 不健康的 unsuccessful 不成功的 uncommon不普通的 unpleasant令人不快的 unfortunate不幸的 irregular不规则的 illegal非法的 invisible看不见的 3. re- 表示“重新,再”,用在动词前。如: rebuild 重新建造 recycle 再循环 reconsider 重新考虑 review 复习二、后缀 I.形容词后缀 1. -able (n./v.→adj.)表示“可以……的;显示……性质”。如:respectable 可敬的 eatable 可吃的 comfortable 舒服的 valuable 有价值的 fashionable 时髦的 loveable 可爱的 2. -ful (n./v.→adj.) 表示“充满……的”。如: beautiful 漂亮的 successful 成功的 wonderful 精彩的 mouthful 满嘴的 shameful 可耻的 hopeful 充满希望的 3. -less (n.→adj.) 表示“没有……的”。如: jobless 无业的 cordless 无线的 homeless 无家可归的 helpless 无助的 4. -ous (n.→adj.)表示“具有……性质的”。如: nervous 紧张的 famous 著名的 dangerous 危险的 poisonous 有毒的 mountainous 山区的 humorous 幽默的

(完整版)数学表达式计算(c语言实现)

一、设计思想 计算算术表达式可以用两种方法实现: 1.中缀转后缀算法 此算法分两步实现:先将算术表达式转换为后缀表达式,然后对后缀表达式进行计算。具体实现方法如下: (1)中缀转后缀 需要建一个操作符栈op和一个字符数组exp,op栈存放操作符,字符数组用来存放转换以后的后缀表达式。首先,得到用户输入的中缀表达式,将其存入str数组中。 对str数组逐个扫描,如果是数字或小数点,则直接存入exp数组中,当扫描完数值后,在后面加一个#作为分隔符。 如果是操作符,并且栈为空直接入栈,如果栈不为空,与栈顶操作符比较优先等级,若比栈顶优先级高,入栈;如果比栈顶优先级低或相等,出栈将其操作符存到exp数组中,直到栈顶元素优先等级低于扫描的操作符,则此操作符入栈;如果是左括号,直接入栈,如果是右括号,出栈存入exp数组,直到遇到左括号,左括号丢掉。然后继续扫描下一个字符,直到遇到str中的结束符号\0,扫描结束。结束后看op栈是否为空,若不为空,继续出栈存入exp数组中,直到栈为空。到此在exp数组最后加结束字符\0。 我们就得到了后缀表达式。 (2)后缀表达式计算 此时需要一个数值栈od来存放数值。对exp数组进行逐个扫描,当遇到数字或小数点时,截取数值子串将其转换成double类型的小数,存入od栈中。当遇到操作符,从栈中取出两个数,进行计算后再放入栈中。继续扫描,知道扫描结束,此时值栈中的数值就是计算的结果,取出返回计算结果。 2.两个栈实现算法 此算法需要两个栈,一个值栈od,一个操作符栈op。将用户输入的数学表达式存入str数组中,对其数组进行逐个扫描。 当遇到数字或小数点,截取数值子串,将其转换成double类型的数值存入od栈中; 当遇到左括号,直接入op栈;遇到右括号,op栈出栈,再从值栈od中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到操作符栈栈顶为左括号,将左括号丢掉。 如果遇到操作符,若op栈为空,直接入栈;若栈不为空,与栈顶元素比较优先等级,若比栈顶操作符优先等级高,直接入op栈,如果低于或等于栈顶优先等级,op栈出栈,再从值栈中取出两个数值,计算将其结果存入值栈中,一直进行此操作,直到栈顶优先等级低于扫描的操作符等级,将此操作符入op栈。继续扫描直到遇到str中的结束字符\0,扫描结束。此时看操作符栈是否为空,若不为空,出栈,再从值栈中取出两个数值进行计算,将其结果存入值栈,一直进行此操作,直到操作符栈为空。此时把值栈中的数值取出,即为所得的最终计算结果。 二、算法流程图 第一种算法:中缀转后缀算法

C语言 后缀表达式计算

一、设计思想 计算算数表达式并求值,采取的共有两种方法: 1.先将算数表达式转化为后缀表达式,然后对后缀表达式进行计算。 2.对算数表达式进行直接的计算。 第一种算法 这种解决方案又分为两步: 1.将表达式先转化为后缀表达式的字符串数组 2.利用后缀表达式进行计算 在转化过程中,第一,建立一个存符号的栈,和一个字符串数组,用来存放转化以后的表达式 然后,对于得到的用户输入的字符串进行逐个的扫描,如果是数组或者小数点,则直接存放到数组中,并且在后面加入一个分隔符,如果是操作符,则和栈中的已存的进行比较,如果比栈中的操作符的优先级高,则直接入栈,如果优先级低或相等,则栈中元素出栈,存到字符串中,然后再次检查栈顶,直到栈中元素的优先级低于扫描操作符,则此操作符入栈,然后扫描下一个字符,直到遇到字符串的结束符号\0,扫描结束。数组中存的就是后缀表达式。得到后缀表达式后,进行计算,要用到数值栈。首先要将字符表示的数字转化为浮点小数,然后进行扫描,遇到数值,放入栈中,遇到操作符,就从栈中取出两个数,进行计算后再放入栈中,扫描下一个,最后的计算结果就存到了栈中,直接取出栈内元素,就是计算的最后结果。 第二种算发 首先要建立两个栈,一个用来存放操作符,一个用来存放数值。开始对用户输入的字符串进行扫描,如果是数字字符或者小数点,则将字符转化为浮点数存到数栈里,如果是操作符,则观察符号栈,如果栈顶元素的优先级低于观察的操作符,则操作符入栈,如果栈顶元素的优先级高于或者等于观察的操作符,则从数值栈中取出两个浮点数,从符号栈中取出栈顶的操作符,然后进行相应的数值计算,所得的结果再存到数值栈中,重复这样的操作,直到符号栈中栈顶元素的优先级低于观察的操作符,则此操作符入栈,然后对下一个字符进行扫描。如果是左括号,则不进行优先级的比较,直接入栈,入栈后优先级为-1。如果是右括号,则从数值栈中取两个操作数,符号栈中取出一个符号,然后进行计算后得数放入数栈中,不断进行此类操作,直到从栈中取出的是左括号为止,左括号去掉,扫描下一个。扫描结束后,计算也结束了,计算的结果就存放在数值栈中,最后把数值栈中的数取出,就是所得的计算结果。 容错的算法简要: 括号匹配:当扫描到左括号是,左括号直接入栈,扫描到右括号时,则左括号出栈,如果栈为空,则右括号多,如果最后栈中还有括号,则左括号多。给出错误提示。 除数不为0:当扫描到'/'时,就判断其后面的数字是否为0,如果为0报错。 取余运算:取余运算时,操作数判断是否为整数,不为整数报错。 二、算法流程图 第一种算法:先将表达式转化为后缀表达式,然后计算 其主函数流程图为:

常用的前缀和后缀

一、常用的前缀和后缀 1、常用前缀 aero-:concerning the air of aircraft plane—aeroplane space—aerospace anti-:against;opposite of nuclear—antinuclear matter—antimatter war—antiwar auto-:of or by oneself biography—autobiography criticism—autocriticism be-:to treat as the stated thing friend—befriend little—belittle bi-:two;twice;double lingual—bilingual cycle—bicycle bio-:concerning living things chemistry—biochemistry sphere—biosphere by-,bye-:less important produce—by-produce way—byway centi-:hundredth part grade—centigrade meter—centimeter co-:together,with author—coauthor exist—coexist col-:( used before l ) together,with location—collocation com-:( used before b,m,p ) together,with

passion—compassion con-:together,with centric—concentric federation—confederation contra-:opposite diction—contradiction natural—contranatural cor-:( used before r ) together,with relate—correlate respond—correspond counter-:opposite act—counteract attack—counterattack cross-:across;going between the stated things and joining them country—crosscountry breed—crossbreed de-:showing an opposite;to remove;to reduce code—decode value—devalue dis-:not;the opposite of advantage—disadvantage agree—disagree honest—dishonest em-:( used before b,m,p ) to cause to become body—embody power—empower en-:to cause to become;to make danger—endanger large—enlarge ex-:former ( and still living ) minister—ex-minister wife—ex-wife

后缀表达式求值的算法及代码

#include #include struct node // 栈结构声明 { int data; // 数据域 struct node *next; // 指针域 }; typedef struct node stacklist; // 链表类型 typedef stacklist *link; // 链表指针类型 link operand=NULL; // 操作数栈指针 link push(link stack,int value) // 进栈 { link newnode; // 新结点指针 newnode=new stacklist; // 分配新结点 if (!newnode) { printf("分配失败!"); return NULL; } newnode->data=value; // 创建结点的内容 newnode->next=stack; stack=newnode; // 新结点成为栈的开始return stack; } link pop(link stack,int *value) // 出栈 { link top; // 指向栈顶 if (stack !=NULL) { top=stack; // 指向栈顶 stack=stack->next; // 移动栈顶指针 *value=top->data; // 取数据 delete top; // 吸收结点 return stack; // 返回栈顶指针} else *value=-1; } int empty(link stack) // 判栈空 { if (stack!=NULL)

英语中常用的前缀和后缀

英语中常用的前缀和后缀 aero:concerning the air or aircraft plane(飞机)—aeroplane(飞机) space(空间, 间隔)—aerospace(航空宇宙) anti: against;opposite of nuclear([核]核子的)—antinuclear(反对使用核武器的) matter(物质)—antimatter(反物质) war(战争、作战、打仗)—antiwar(反战的, 反对战争的) auto: of or by oneself biography(传记)—autobiography(自传) criticism(批评, 批判)—autocriticism(自我反省, 自我检讨) be:to treat as the stated thing friend(朋友, 助手)—befriend(待人如友, 帮助) little(很少的, 矮小的,很少)—belittle(轻视, 使渺小, 使...显得渺小)bi: two;twice;double lingual(语言的)—bilingual(能说两种语言的) cycle(自行车)—bicycle(脚踏车, 自行车) bio:concerning living things chemistry(化学)—biochemistry(生物化学) sphere(圈子)—biosphere(生物圈) by—:less important product(产品, 产物,)—by-product(副产品, 附加产物) way(路,道路)—byway(小道) centi: hundredth part grade(等级)—centigrade(分为百度的, 百分度的, 摄氏温度的)meter(米)—centimeter(厘米) co: together, with author(作家, 创造者)—coauthor(合著者, 共同执笔者,合著)exist(存在, 生存)—coexist(共存) col:(used before l) together, with location(位置, 场所)—collocation(排列, 配置) com:(used before b, m, p)together, with passion(激情, 热情)—compassion(同情,怜悯)

后缀表达式转化为前缀表达式并求值

#include #include #include #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OK 1 #define OVERFLOW -2 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Selemtype; typedef int Status; #define MAX 50 char string1[MAX]; //定义两个字符串分别存放中缀表达式和后缀表达式char string2[MAX]; int result; typedef struct { Selemtype *base; //在构造之前和销毁之后,base的值为NULL Selemtype *top; //栈顶指针 int stacksize; //当前分配的存储空间,以元素为单位 }SqStack; Status InitStack(SqStack *S); Status Push(SqStack *S,Selemtype e); Status Pop(SqStack *S,Selemtype e); Status InitStack(SqStack *S) { //构造一个空栈S S->base=(Selemtype*)malloc(STACK_INIT_SIZE*sizeof(Selemtype)); if(!S->base) return OVERFLOW; //存储分配失败 S->top=S->base; S->stacksize=STACK_INIT_SIZE; return OK; } Status Push(SqStack *S,Selemtype e) { //插入元素e为新的栈顶元素 if(S->top-S->base>=S->stacksize)

常见的前后缀

常见得前缀 一、表示否定意义得前缀 un-不做相反动作dis-不做相反动作in- 不 im-不ir-不il- 不non- 不,非 【猜一猜】①unhappy ②untrue ③undress④undo⑤disagree(ment)⑥disown ⑦disinect ⑧non-existent⑨non-conductor 【key】①不高兴②不真实③暴露,使卸去装饰④解开,松开⑤不一致,不适合(争执,争论) ⑥否认⑦消毒⑧不存在得⑨绝缘体 二、表示前,先前意义得前缀 husband ex—husband(前夫) see oresee(预知,预见) history prehistory(史前时期) claim proclaim(宣告,宣布) 瞧完这单词得对比大家一定知道这一组前缀主要就是表示前,先前,预先 前缀ex-,汉语意思就是“先前",它主要就是与表示“人”得名词搭配、 例如:ex—minister-ormerminister(前任大使) 前缀ore-,汉语意思就是“先前得”、“在前面得”,它可以加在某些动词与名词前面。例如:oretell预言前缀pre—,汉语意思就是“在……前”,它主要就是加在名词前面,也与少量得形容词、动词搭配、 前缀pro—,汉语意思就是“向前,在前,预先”,可以与名词、动词、形容词搭配。 例如:propelling(向前推进得) 【猜一猜】①ex-president ②orecast ③orecourt④orehead ⑤oreground⑥preadult ⑦preannounce ⑧precook ⑨preace 【key】①前任总统②预见,预测③前院,(篮球)前(场)球④前额,(任何事物得)前部⑤前景,最显著得位置⑥成年前得⑦预告,事先宣告⑧预煮,预先烹调(食物)⑨前言 三、表示错误得,不良意义得前缀 spell misspell拼错 treat maltreat虐待,滥用 根据前面单词得比较我们能得出 mis—错误地mal-不良得 【猜一猜】①misinorm ②malunction 【key】①告诉错误得消息②故障 四、表示空间位置、方向关系得前缀 请大家熟记下面得顺口溜里in(im,inter, intro)外out。上over(super,up)下sub(under)、前pro(pre)后po st。还有中间就是medi(med,mid)、 前缀意义例词 in—,im-表示“向内,在内,背于”inside里面;import进口 inter-,intel—表示“在……间,相互”international国际得;internet互联网 intro-表示“向内,在内,内侧”introduce介绍 en—表示“在内,进入”encage 关在笼中,把…关起来 out—表示“在上面,在外部,在外”outline 大纲,轮廓,略图;outside外面 ex-,ec—,es-表示“外部,外”exit,出口;expand 扩张,张开,发展 extra- 表示“额外”extraction提取 up—表示“向上,向上面,在上”upward在上面地,向上地;uphold 支持,

数据结构计算器(包括中缀转换后缀)课程设计报告

课程设计报告 题目:计算表达式的值 1.问题描述 对于给定的一个表达式,表达式中可以包括常数、算术运行符(“+”、“-”、“*”、“/”)和括号,编写程序计算表达式的值。 基本要求:从键盘输入一个正确的中缀表达式,将中缀表达式转换为对应的后缀表达式,并计算后缀表达式的值。对于表达式中的简单错误,能够给出提示,并给出错误信息;表达式中可以包括单个字母表示的变量。 测试数据:任意选取一个符合题目要求的表达式。 提高要求:(1)能够处理多种操作符。 (2)实现包含简单运算的计算器。 (3)实现一个包含简单运算和函数运算的计算器。 2.需求分析 (1)软件的基本功能 本软件实在win32工程下实现的带有界面和图标的功能较为齐全的计算器。 此计算器分三个方面进行计算,分别为数值表达式的计算,字母表达式的计算和函数计算。可由键盘或用鼠标点击按键输入带有数字或字母的中缀表达式,程序可以将输入的带有数字或字母的中缀表达式转换成对应的后缀表达式,并计算只含有数字的后缀表达式的值。本软件支持含小数、多位数等多种操作数的处理,可以计算含加、减、乘、除、百分号、求余、求幂,求阶乘,求三角函数的值等多种运算符和函数的表达式 (2)输入/输出形式 用户可通过打开图标弹出来的计算器界面任意点击操作。对于在输入时发生的简单错误,软件通过弹出对话框给出提示并且在提示错误的同时自动将用户的出错输入略去转化成正确的表达式进行计算,用户也可选择清楚操作然后重新输入a.对于数值和函数表达式软件会输出其表达式的后缀表达式和计算结果并保留六位小数; b.对于字母表达式因字母无法进行数值运算,软件仅输出其后缀表达式的值;清楚按钮可以清楚有已经输入或输出的数据从头计算; 软件窗口可实现最小化。并且输入编辑框可进行修改,复制,粘贴等操作,但后缀表达式和求值结果的编辑框中的内容不可修改,只能执行复制操作。

最常见的前缀和后缀

1 / 5 英语中的派生词的构成主要有三种: 合成(由两个或两个以上的单词合成的单词);派生(指一个词根加上前缀或后缀构成的单词);转化(一种词性转化成另一种或几种词性的单词)。本文重点通过对前缀和后缀的剖析解读派生词的意义和特点。 先看下表: 词缀 特点 类别前缀通常不改 变词性词义词类 agree (v.)→ disagree(v.) 同意→不同意 health (n.)→ healthy (adj.) 健康→健康的 care (n.)→ careless (adj.) 小心→粗心的 意义改变后缀一般改变 2 / 5 词性词义改变不 大, 但否定意义后

缀除外 一、前缀 1. dis-表示意义相反,主要用在动词之前,间或用于名词或形容词前。如: appear (v.出现) →disappear (v.消失), 再如: dislike不喜欢discover发现disobey不遵从disbelieve不相信dishonest(adj.)不诚实的disadvantage (n.)不利条件,缺点2. in-, im-, un-, il-, ir-用在形容词前,表示否定意义。如:indirect间接的incorrect不正确的inactive不活动的impossible不可能的unable不能的unhealthy不健康的unfortunate不幸的irregular不规则的illegal非法的 invisible看不见的 3. re-表示“重新,再”,用在动词前。如: rebuild重新建造recycle再循环reconsider重新考虑review复习二、后缀 I.形容词后缀 1. -able (n./v.→adj.)表示“可以??的;显示??性质”。如:valuable有价值的fashionable时髦的loveable可爱的 3 / 5 2. -ful (n./v.→adj.) 表示“充满??的”。如: beautiful漂亮的successful成功的wonderful精彩的 mouthful满嘴的shameful可耻的hopeful充满希望的

后缀表达式的计算

#include #include #include #include using namespace std; int priority(char op) //运算符的优先级 { switch(op) { case '(': return 0; break; case '+': case '-': return 1; break; case '*': case '/': return 2; break; default: return -1; break; } } bool IsOperator(char op) //是否为运算符 { if (op == '+' || op == '-' || op == '*' || op == '/') { return true; } return false; } void inTOpost(char s[],vector &v) //转为后缀表达式{ stack stk; int i = 0,len = strlen(s); while(i < len) { if(s[i] >= '0' && s[i] <= '9') {

v.push_back(s[i]); v.push_back(' '); } else if (s[i] == '(') { stk.push(s[i]); } else if (s[i] == ')') { while(stk.top() != '(') { v.push_back(stk.top()); v.push_back(' '); stk.pop(); } stk.pop(); } else if (IsOperator(s[i])) { if (!stk.empty()) { while(!stk.empty() && priority(s[i]) <= priority(stk.top())) { v.push_back(stk.top()); v.push_back(' '); stk.pop(); } } stk.push(s[i]); } i++; } while(!stk.empty()) { v.push_back(stk.top()); v.push_back(' '); stk.pop(); } } bool compute(vector s,int &res) //计算后缀表达式的值 { int i = 0,num; int len = s.size();

常用前缀和后缀

专升本常用前缀和后缀 1.常用前缀 aero:concerning the air or aircraft plane(飞机)—aeroplane(飞机) space(空间, 间隔)—aerospace(航空宇宙) anti: against;opposite of nuclear([核]核子的)—antinuclear(反对使用核武器的) matter(物质)—antimatter(反物质) war(战争、作战、打仗)—antiwar(反战的, 反对战争的) auto: of or by oneself biography(传记)—autobiography(自传) criticism(批评, 批判)—autocriticism(自我反省, 自我检讨) be:to treat as the stated thing friend(朋友, 助手)—befriend(待人如友, 帮助) little(很少的, 矮小的,很少)—belittle(轻视, 使渺小, 使...显得渺小)bi: two;twice;double lingual(语言的)—bilingual(能说两种语言的) cycle(自行车)—bicycle(脚踏车, 自行车) bio:concerning living things chemistry(化学)—biochemistry(生物化学) sphere(圈子)—biosphere(生物圈) by—:less important product(产品, 产物,)—by-product(副产品, 附加产物) way(路,道路)—byway(小道) centi: hundredth part grade(等级)—centigrade(分为百度的, 百分度的, 摄氏温度的) meter(米)—centimeter(厘米) co: together, with author(作家, 创造者)—coauthor(合著者, 共同执笔者,合著) exist(存在, 生存)—coexist(共存) col used before l) together, with location(位置, 场所)—collocation(排列, 配置) com used before b, m, p)together, with passion(激情, 热情)—compassion(同情,怜悯) con:together, with centric(中心的, 中央的)—concentric(同中心的) federation(同盟, 联邦, 联合, 联盟)—confederation(联邦) contra pposite diction(措辞, 用语, 言语)—contradiction(反驳, 矛盾)

数学表达式解析(前缀中缀后缀)

它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。 举例: (3 + 4) × 5 - 6 就是中缀表达式 - × + 3 4 5 6 前缀表达式 3 4 + 5 × 6 - 后缀表达式 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。 前缀表达式(前缀记法、波兰式) 前缀表达式的运算符位于操作数之前。 前缀表达式的计算机求值: 从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。 例如前缀表达式“- × + 3 4 5 6”: (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) 遇到括号时:

相关文档
最新文档