算术表达式求值运算实验指导书 联系客服

发布时间 : 星期日 文章算术表达式求值运算实验指导书更新完毕开始阅读bb596f6025c52cc58bd6be2b

参数:char str[]—存放输入的表达式 返回值:无

(4)表达式计算函数:excute 功能:完成表达式的计算

格式:int excute(char *str,double *Result) 参数:char *str—要计算的表达式字符串 double *Result—计算结果值 返回值:1—计算成功 0—计算失败

(5)确定当前字符类型函数:GetCharType 功能:确定当前要处理的字符的类型

格式:int GetCharType(char ch) 参数:char ch—当前要处理的字符

返回值:若为算符,返回字符的编码(一维数组下标) 若为数字,返回符号常熟DIGIT(数字) 若为小数点,返回符号常熟POINT(小数点) 若不是定义的表达式的字符,返回-1。

六、算法描述

1、表达式计算算法描述

设栈顶指针:int topTr—运算符栈顶指针 topNd—操作数栈顶指针

表达式字符指针:int pp—指向表达式中当前要处理的字符 开始时,把表达式开始符“#”(编码)放入栈中。

设当前要处理的字符类型为CharType。以当前要处理的字符为参照来确定下一步要作的处理:

●若当前字符为非法字符:则结束处理,返回出错标志(0);

●若当前字符是数字:表示遇到表达式中的操作数,则识别出该操作数; ●若当前字符是小数点:表示遇到以小数点开头的操作数,则识别出该操作数; ●若当前字符是+、-、*、/运算符:则用栈顶运算符与当前运算符比较优先性:

若对应的数组元素为-1,则当前运算符(运算符编码)进栈,调整pp指向下

一个字符。

若对应的数组元素为1,则取运算符栈顶运算符和操作数栈顶操作数进行运算,

参与运算的运算符和操作数出栈,运算结果进操作数栈。实现为:

OPND[topNd-2]=OPND[topNd-2] op OPBD[topNd-1]; topNd--; topTr--;

●若当前字符是左括号(: 则左括号进栈,pp指向下一个字符

●若当前字符是右括号):

⊙若栈顶是左括号,则左括号出栈,pp指向下一个字符

⊙若栈顶是运算符,则取运算符栈顶运算符和操作数栈顶操作数进行运算,参

与运算的运算符和操作数出栈,运算结果进操作数栈。实现为:

OPND[topNd-2]=OPND[topNd-2] op OPBD[topNd-1]; topNd--; topTr--;

重复该操作,直到栈顶出现左括号“(”。

⊙若栈顶是#,则左括号和右括号不配对,结束处理,返回出错标志(0)

●若当前字符为#:依次从运算符栈取出运算符和从操作数栈取出操作数进行计算,直到运算符栈的栈顶为#为止。

若运算符栈顶为#,当前字符也为#,则表达式计算结束,返回计算结果值和计算成功标志(1)。

2、字符型数字常数转换为数值型常数的方法

因为程序处理的表达式是以字符串形式出现的,表达式中每个数值型常数也是有一个一个的数字字符组成。处理程序必须把字符串形式的常数转换为数值形式的常数。

(1)整数的转换方法

我们知道,一个数值型常数3256可以表示为: 3256=((3*10+2)*10+5)*10+6

相应的,一个字符串型的数字常数“3256”转换为数值型常数可以表示为: (((‘3’-48)*10+(‘2’-48))*10+(‘5’-48))*10+(‘6’-48) 每个字符的ASCII码指减去48就是该字符对应数字值。

实现方法:依次读入数字字符,用前面读入子字符串对应的数值型值乘以10,再加上当前字符的数字值,就是当前读入子字符串对应的数值型值。用C语言描述如下:

number=0;

while(str[pp]>='0' && str[pp]<='9') { number=number*10+(str[pp]-48);

pp++; }

(2)小数的转换方法

一个小数常数0.2345可以表示为: 0.2345=2/10+3/100+4/1000+5/10000

相应的,一个字符串表示的小数“0.2345”转换为数值型小数可以表示为: “0.2345”=(‘2’-48)/10+(‘3’-48)/100+(‘4’-48)/1000+(‘5’-48)/10000 假设当前字符指针指向小数点字符,转换方法描述为:

number=0;

temp=10.0; pp++;

while(str[pp]>='0' && str[pp]<='9')

{ number=number+(str[pp]-48)/temp; temp=temp*10; pp++; }

(3)既有整数又有小数部分的实数的转换算法

综合前面两部分算法,既有整数又有小数部分的实数的转换算法描述如下:

number=0;

while(str[pp]>='0' && str[pp]<='9') //处理实数的整数部分 { number=number*10+(str[pp]-48);

pp++; }

if(str[pp]=='.') //遇到小数点 { temp=10.0; pp++;

while(str[pp]>='0' && str[pp]<='9') //处理实数的小数部分 { number=number+(str[pp]-48)/temp; temp=temp*10; pp++; } }

七、思考题

1、若表达式中的数据带有正负号的实数字符串该怎样进行转换?

2、对于指数形式的实数字符串该怎样进行转换?

八、部分函数代码

#include #include #include #define PLUS 0 #define MINUS 1 #define POWER 2 #define DIVIDE 3 #define LEFTP 4 #define RIGHP 5 #define STARTEND 6 #define DIGIT 7 #define POINT 8

#define NUM 7 #define NO 32767 #define STACKSIZE 20 //运算符

char a[]={'+','-','*','/','(',')','#'}; //优先关系矩阵,规定:=为0,>为1,<为-1,空为NO int PriorityTable[7][7]={{ 1, 1,-1,-1,-1, 1, 1}, { 1, 1,-1,-1,-1, 1, 1}, { 1, 1, 1, 1,-1, 1, 1}, { 1, 1, 1, 1,-1, 1, 1}, {-1,-1,-1,-1,-1, 0, NO}, { 1, 1, 1, 1,NO, 1, 1}, {-1,-1,-1,-1,-1,NO, 0} }; int menu(void);

/***************************/ /* 输入表达式函数 */ /***************************/ void InputExpression(char str[]) { int len;

printf(\ scanf(\ len=strlen(str); str[len]='#'; str[len+1]='\\0'; }

/*************************************************/ /* 确定当前字符类型 */ /*************************************************/ /* 若为运算符,则返回运算符在运算符数组中的序号 */ /* 若为数字字符,则返回DIGIT */ /* 若为小数点字符,则返回POINT */ /* 否则为非法字符,返回-1 */ /*************************************************/ int GetCharType(char ch) { int i;

for(i=0;i='0' && ch<='9') return(DIGIT);