发布时间 : 星期日 文章算术表达式求值运算实验指导书更新完毕开始阅读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
#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