表达式求值的C实现

it2022-05-09  29

 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;    *= *(s.top-1);    return OK;}Status GetTop_OPND (OPNDStack s, OperandType *e){    if(s.top == s.base)       return ERROR;    *= *(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).basereturn ERROR;    (*s).top--*= *(*s).top;    return OK;}Status Pop_OPND (OPNDStack *s, OperandType *e){    if((*s).top == (*s).basereturn ERROR;    (*s).top--*= *(*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;    *= *(s.top-1);    return OK;}Status GetTop_OPND (OPNDStack s, OperandType *e){    if(s.top == s.base)       return ERROR;    *= *(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).basereturn ERROR;    (*s).top--*= *(*s).top;    return OK;}Status Pop_OPND (OPNDStack *s, OperandType *e){    if((*s).top == (*s).basereturn ERROR;    (*s).top--*= *(*s).top;    return OK;}

成编译后测试:(((6+6)*6+3)*2+6)*2

转载于:https://www.cnblogs.com/yequan/archive/2009/04/30/1446934.html

相关资源:c编写服务器程序

最新回复(0)