/* 表达式求值,输入一个表达式,如1+2*3#,程序可计算出结果为7 支持以下符号: + - * / ( ) ^ . 可以计算整数、小数 其中^表示次方,2^5表示2的5次方 */
/*头文件*/
#include
/*宏定义*/
#define INIT_STACK_SIZE 100 #define SET_NUM 8 #define N 100
/*字符优先级表*/
unsigned char prior[SET_NUM][SET_NUM] = { /* '+' '-' '*' '/' '(' ')' '#' '^' */ /*'+'*/'>', '>', '<', '<', '<', '>', '>', '<', /*'-'*/'>', '>', '<', '<', '<', '>', '>', '<', /*'*'*/'>', '>', '>', '>', '<', '>', '>', '<', /*'/'*/'>', '>', '>', '>', '<', '>', '>', '<', /*'('*/'<', '<', '<', '<', '<', '=', ' ', '<', /*')'*/'>', '>', '>', '>', ' ', '>', '>', '>', /*'#'*/'<', '<', '<', '<', '<', ' ', '=', '<', /*'^'*/'>', '>', '>', '>', '<', '>', '>', '>' };
unsigned char priorSet[SET_NUM] = {'+', '-', '*', '/', '(', ')', '#', '^'};
/*结构体定义,这是用来存放字符的栈*/ typedef struct { char *base; char *top; int stacksize; } SqStackC;
/*结构体定义,这是用来存放数字的栈*/
typedef struct { double *base; double *top; int stacksize; } SqStackN;
void initStackN(SqStackN &); void initStackC(SqStackC &); void pushN(SqStackN &, double); void pushC(SqStackN &, double); void popN(SqStackN &, double &); void popC(SqStackN &, double &); double calculate(double, char, double); int findInSet(char);
char compare(char, char); void getSolution();
/*主函数*/ void main() { getSolution(); }
/*初始化数字栈*/
void initStackN(SqStackN &S) { S.base = (double*) malloc(INIT_STACK_SIZE * sizeof(double)); S.top = S.base; S.stacksize = INIT_STACK_SIZE; }
/*初始化字符栈*/
void initStackC(SqStackC &S) { S.base = (char*) malloc(INIT_STACK_SIZE * sizeof(char)); S.top = S.base; S.stacksize = INIT_STACK_SIZE; }
/*向数字栈中存放数字*/
void pushN(SqStackN &S, double x) { if (S.top-S.base >= S.stacksize)
return; *(S.top++) = x; }
/*向字符栈中存放字符*/
void pushC(SqStackC &S, char x) { if (S.top - S.base >= S.stacksize) return; *(S.top++) = x; }
/*从数字栈中取出数字*/
void popN(SqStackN &S, double &x) { if (S.top==S.base) return; x = *(--S.top); }
/*从字符栈中取出字符*/
void popC(SqStackC &S, char &x) { if (S.top == S.base) return; x = *(--S.top); }
/*这个函数返回a operation b的值。假如operation为'+',则返回a+b的值*/ double calculate(double a, char operation, double b) { /*判断operation,返回对应的计算结果*/ switch (operation) { case '+': return a + b; case '-': return b - a; case '*': return a * b; case '/': return b / a; case '^': return pow(b, a); default:
return 0; } }
/*查找字符c在priorSet中的什么位置*/ /*priorSet是所支持的所有字符的集合*/ int findInSet(char c) { int i; for (i = 0; i < SET_NUM; i++) { if (priorSet[i] == c) return i; } return -1; }
/*比较optrtop和c的优先关系*/ char compare(char optrtop, char c) { int i, j; /*从priorSet中取出optrtop和c的位置*/ i = findInSet(optrtop); j = findInSet(c); /*如果返回值中有-1表示这个符号不支持,结束程序*/ if (i == -1 || j == -1) { printf(\不支持的符号类型\\n\ exit(0); } /*否则返回二者优先级关系*/ else return prior[i][j]; }
/*取得计算结果*/ /* 解释下代码处理数字的原理:假如输入为10+2.2*3-2# 循环会从这个字符串第一个位置开始,也就是1 如果当前字符是个数字,则要把这个数字从字符串里取出来 这个时候涉及两个问题,一是数字可能是大于10的整数,二是可能有小数。 处理方法是这样的: 当遇到数字,先将数字保存在n上,判断下一个字符是数字还是运算符
如果是数字,则将n乘以10加上这个数字,这样即可以处理大于10的数字。 如果遇到运算符,就退出循环去处理运算符 如果遇到的是小数点,表示这个数字是小数。 小数不会立刻计算出来,而是先将小数点忽视掉,将整数计算出。 比如2.2会先计算成22
变量j和begin在遇到小数点时候用来计算小数点后面有几个数字,即这个小数有多少位。 当begin = 1时候,表示现在要计算小数点后的数字位数。这时候j会在每次循环加1 这样计算后,n = 22, j = 1; 此时算 n = n / pow(10, j);即将n缩小10的j次方。就变成了2.2 */
void getSolution() { /*operation是当前的运算符*/ char operation; /*temp是输入的字符串*/ char temp[N]; /*i是循环变量,j和begin用来控制什么时候计算出小数*/ int i = 0, j = -1, begin = 0; /*sum是每次的计算结果,a和b是从数字栈中取出的数字,n用来存放从字符串中取出的数*/ double sum, a, b, n; /*定义堆栈并初始化*/ SqStackC OPTR; SqStackN OPND; initStackC(OPTR); initStackN(OPND); /*向字符栈中压入#,标志开始*/ pushC(OPTR, '#'); /*获得输入*/ printf(\请输入一个表达式,输入#结束\\n\ gets(temp); /*开始计算,当遇到#表示结束*/ while (temp[i] != '#' || *(OPTR.top - 1) != '#') { /*如果当前字符是个数字字符*/
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库C语言表达式求值(带详细注释)在线全文阅读。
相关推荐: