Stack.h:
Code //-----------------------------------//Stack.h//实现运算符栈和运算数栈的抽象数据类型//及一些预定义类型//-----------------------------------#include <stdlib.h>#include <stdio.h>#include <math.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define OVERFLOW -2#define STACK_INIT_SIZE 100 //存储空间初始分配量#define STACKINCREMENT 10 //存储空间分配增量typedef int Boolean; //定义布尔类型typedef int Status;typedef double OperandType; //操作数typedef char OperatorType; //操作符typedef struct{ OperatorType *base; //在栈构造之前和销毁之后,base的值为NULL OperatorType *top; //栈顶指针 int stacksize; //当前已分配的存储空间,以元素为单位}OPTRStack;typedef struct{ OperandType *base; OperandType *top; int stacksize;}OPNDStack;//初始化Status InitStack_OPTR (OPTRStack *s){ (*s).base = (OperatorType *)malloc(STACK_INIT_SIZE * sizeof(OperatorType)); if(!(*s).base) exit(OVERFLOW); (*s).top = (*s).base; (*s).stacksize = STACK_INIT_SIZE; return OK;}Status InitStack_OPND (OPNDStack *s){ (*s).base = (OperandType *)malloc(STACK_INIT_SIZE * sizeof(OperandType)); if(!(*s).base) exit(OVERFLOW); (*s).top = (*s).base; (*s).stacksize = STACK_INIT_SIZE; return OK;}//取栈顶元素Status GetTop_OPTR (OPTRStack s, OperatorType *e){ if(s.top == s.base) return ERROR; *e = *(s.top-1); return OK;}Status GetTop_OPND (OPNDStack s, OperandType *e){ if(s.top == s.base) return ERROR; *e = *(s.top-1); return OK;}//进栈Status Push_OPTR (OPTRStack *s, OperatorType e){ if((*s).top-(*s).base >= (*s).stacksize) { OperatorType *newbase = (OperatorType *) realloc((*s).base, ((*s).stacksize + STACKINCREMENT) * sizeof(OperatorType)); if(!newbase) exit(OVERFLOW); (*s).base = newbase; (*s).top = (*s).base + (*s).stacksize; (*s).stacksize += STACKINCREMENT; } *(*s).top = e; (*s).top++; return OK;}Status Push_OPND (OPNDStack *s, OperandType e){ if((*s).top-(*s).base >= (*s).stacksize) { OperandType *newbase = (OperandType *) realloc((*s).base, ((*s).stacksize + STACKINCREMENT) * sizeof(OperandType)); if(!newbase) exit(OVERFLOW); (*s).base = newbase; (*s).top = (*s).base + (*s).stacksize; (*s).stacksize += STACKINCREMENT; } *(*s).top = e; (*s).top++; return OK;}//出栈Status Pop_OPTR (OPTRStack *s, OperatorType *e){ if((*s).top == (*s).base) return ERROR; (*s).top--; *e = *(*s).top; return OK;}Status Pop_OPND (OPNDStack *s, OperandType *e){ if((*s).top == (*s).base) return ERROR; (*s).top--; *e = *(*s).top; return OK;}Expression evaluation.c:
Code //---------------------------------//Expression evaluation.c//主函数//---------------------------------//-----------------------------------------------------------------------------------//题目:算术表达式求值//完成时间:2009.03.17//使用C语言编写//程序功能说明://用户通过键盘输入一个表达式,计算机进行判读,如果是合法的表达式就按运算符的优先顺序//给出结果,如果是非法的,就给出非法提示,并让用户重新输入。用户可以输入'#'号来表示//表达式输入完成,也可以选择不输入。//使用了两个栈:操作数栈和操作符栈来实现。并演示了操作过程中栈的变化。//功能限制://不支持大数运算,运算符仅限'+' '-' '*' '/',另外支持括号'(' ')'。//-----------------------------------------------------------------------------------#include "Stack.h"#include "Function.h"void main(){ OperatorType e; OPTRStack optr; OPNDStack opnd; double value, result; int waitingMatch = 0; //等待匹配的左括号数目 int index = 0; //index为读取表达式的游标,n为栈操作自增索引 char str[100], c; //str存放表达式, c为每次从表达式中读入的字符 Boolean valid; //表达式是否合法 Boolean needNum; //接下来是否需要读入数字 enum {NUMBER, OPERATOR, LEFT_BRACKET, RIGHT_BRACKET}State; //接下来不应读入类型(数字,操作符,括号) do { index = 0; value = 0; result = 0; waitingMatch = 0; valid = TRUE; needNum = TRUE; State = OPERATOR; printf("Please enter the expression:"); scanf("%s", &str); //读入表达式 InitStack_OPTR(&optr); InitStack_OPND(&opnd); Push_OPTR(&optr,'#'); c = str[index]; //边读表达式边判断表达式的合法性,并进行一些运算 while (str[index] != '#' && str[index] != '\0' && valid == TRUE) { showStack(optr, opnd); printf("Read character: %c\n", c); if(c >= '0' && c <= '9') { if(State == NUMBER) { valid = FALSE; //如果当前不能是数字,表达式非法 break; } State = LEFT_BRACKET; //数字之后不能是左括号 needNum = FALSE; getValue(str, &index, &value, &valid); //获得操作数 Push_OPND(&opnd, value); printf("Operation: Push_OPND(&opnd, %f)\n", value); } else if(c == '+' || c == '-' || c == '*' || c == '/' || c == '#') { if(State == OPERATOR || needNum == TRUE) { valid = FALSE; //如果当前不能是操作符,表达式非法 break; } needNum = TRUE; //操作符后要有数字与它相匹配 State = RIGHT_BRACKET; //操作符之后不能是右括号 GetTop_OPTR(optr, &e); switch(Precede(e, c)) { case '<': Push_OPTR(&optr, c); printf("Operation: Push_OPTR(&optr, '%c')\n", c); break; //栈顶元素优先权低 case '>': value = Calculate(&optr, &opnd, &valid);//栈顶元素优先权高 Push_OPTR(&optr, c); Push_OPND(&opnd, value); printf("Operation: Calculate(&optr, &opnd, &valid), Push_OPND(&opnd, %f)\n", value); break; } } else if(c == '(' || c == ')') { if(c == '(') { if(State == LEFT_BRACKET) { valid = FALSE; //如果当前不能是右括号,表达式非法 break; } waitingMatch++; Push_OPTR(&optr, '('); printf("Operation: Push_OPTR(&optr, '(')\n"); State = OPERATOR;//左括号之后不能是操作符 } else if(waitingMatch == 0 && c == ')') { valid = FALSE; //括号不匹配,表达式为非法 break; } else if(waitingMatch > 0 && c == ')') //脱括号 { if(State == RIGHT_BRACKET) { valid = FALSE; //如果当前不能是右括号,表达式非法 break; } State = NUMBER; //右括号之后不能是数字 GetTop_OPTR(optr, &e); while(e != '(') { value = Calculate(&optr, &opnd, &valid); Push_OPND(&opnd, value); showStack(optr, opnd); GetTop_OPTR(optr, &e); } Pop_OPTR(&optr, &e); //脱掉左括号 printf("Operation: Remove Bracket\n"); waitingMatch--; } } else { valid = FALSE; //输入非法字符 break; } c = str[++index]; //游标下移 } if(waitingMatch > 0 || needNum == TRUE) //存在未匹配的括号, 等待操作数 valid = FALSE; GetTop_OPTR(optr, &e); //做最后的运算,将栈中还没进行运算的内容做运算 while(e != '#' && valid == TRUE) { showStack(optr, opnd); printf("Read character: %c\n", c); value = Calculate(&optr, &opnd, &valid); Push_OPND(&opnd, value); GetTop_OPTR(optr, &e); printf("Operation: Calculate(&optr, &opnd, &valid), Push_OPND(&opnd, %f)\n", value); } printf("\nExpression: %s\n", str); if(valid == FALSE) printf("Illegal expression! Please re-enter!\n"); }while(valid == FALSE); result = value; printf("The Result: %f\n", result);}Funtion.h:
Code //-----------------------------------//Stack.h//实现运算符栈和运算数栈的抽象数据类型//及一些预定义类型//-----------------------------------#include <stdlib.h>#include <stdio.h>#include <math.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define OVERFLOW -2#define STACK_INIT_SIZE 100 //存储空间初始分配量#define STACKINCREMENT 10 //存储空间分配增量typedef int Boolean; //定义布尔类型typedef int Status;typedef double OperandType; //操作数typedef char OperatorType; //操作符typedef struct{ OperatorType *base; //在栈构造之前和销毁之后,base的值为NULL OperatorType *top; //栈顶指针 int stacksize; //当前已分配的存储空间,以元素为单位}OPTRStack;typedef struct{ OperandType *base; OperandType *top; int stacksize;}OPNDStack;//初始化Status InitStack_OPTR (OPTRStack *s){ (*s).base = (OperatorType *)malloc(STACK_INIT_SIZE * sizeof(OperatorType)); if(!(*s).base) exit(OVERFLOW); (*s).top = (*s).base; (*s).stacksize = STACK_INIT_SIZE; return OK;}Status InitStack_OPND (OPNDStack *s){ (*s).base = (OperandType *)malloc(STACK_INIT_SIZE * sizeof(OperandType)); if(!(*s).base) exit(OVERFLOW); (*s).top = (*s).base; (*s).stacksize = STACK_INIT_SIZE; return OK;}//取栈顶元素Status GetTop_OPTR (OPTRStack s, OperatorType *e){ if(s.top == s.base) return ERROR; *e = *(s.top-1); return OK;}Status GetTop_OPND (OPNDStack s, OperandType *e){ if(s.top == s.base) return ERROR; *e = *(s.top-1); return OK;}//进栈Status Push_OPTR (OPTRStack *s, OperatorType e){ if((*s).top-(*s).base >= (*s).stacksize) { OperatorType *newbase = (OperatorType *) realloc((*s).base, ((*s).stacksize + STACKINCREMENT) * sizeof(OperatorType)); if(!newbase) exit(OVERFLOW); (*s).base = newbase; (*s).top = (*s).base + (*s).stacksize; (*s).stacksize += STACKINCREMENT; } *(*s).top = e; (*s).top++; return OK;}Status Push_OPND (OPNDStack *s, OperandType e){ if((*s).top-(*s).base >= (*s).stacksize) { OperandType *newbase = (OperandType *) realloc((*s).base, ((*s).stacksize + STACKINCREMENT) * sizeof(OperandType)); if(!newbase) exit(OVERFLOW); (*s).base = newbase; (*s).top = (*s).base + (*s).stacksize; (*s).stacksize += STACKINCREMENT; } *(*s).top = e; (*s).top++; return OK;}//出栈Status Pop_OPTR (OPTRStack *s, OperatorType *e){ if((*s).top == (*s).base) return ERROR; (*s).top--; *e = *(*s).top; return OK;}Status Pop_OPND (OPNDStack *s, OperandType *e){ if((*s).top == (*s).base) return ERROR; (*s).top--; *e = *(*s).top; return OK;}成编译后测试:(((6+6)*6+3)*2+6)*2
转载于:https://www.cnblogs.com/yequan/archive/2009/04/30/1446934.html
相关资源:c编写服务器程序