表达式求值的C实现

 Stack.h:

ContractedBlock.gifExpandedBlockStart.gifCode
//-----------------------------------
//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
ExpandedBlockStart.gifContractedBlock.gif
{
    OperatorType 
*base//在栈构造之前和销毁之后,base的值为NULL
    OperatorType *top;  //栈顶指针
    int stacksize;  //当前已分配的存储空间,以元素为单位
}
OPTRStack;

typedef 
struct
ExpandedBlockStart.gifContractedBlock.gif
{
    OperandType 
*base;
    OperandType 
*top;
    
int stacksize;
}
OPNDStack;

//初始化
Status InitStack_OPTR (OPTRStack *s)
ExpandedBlockStart.gifContractedBlock.gif
{
    (
*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)
ExpandedBlockStart.gifContractedBlock.gif
{
    (
*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)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(s.top == s.base)
       
return ERROR;
    
*= *(s.top-1);
    
return OK;
}


Status GetTop_OPND (OPNDStack s, OperandType 
*e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(s.top == s.base)
       
return ERROR;
    
*= *(s.top-1);
    
return OK;
}

//进栈
Status Push_OPTR (OPTRStack *s, OperatorType e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top-(*s).base >= (*s).stacksize)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
       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)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top-(*s).base >= (*s).stacksize)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
       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)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top == (*s).basereturn ERROR;
    (
*s).top--*= *(*s).top;
    
return OK;
}


Status Pop_OPND (OPNDStack 
*s, OperandType *e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top == (*s).basereturn ERROR;
    (
*s).top--*= *(*s).top;
    
return OK;
}

Expression evaluation.c:

ContractedBlock.gifExpandedBlockStart.gifCode
//---------------------------------
//Expression evaluation.c
//主函数
//---------------------------------

//-----------------------------------------------------------------------------------
//题目:算术表达式求值
//完成时间:2009.03.17
//使用C语言编写
//程序功能说明:
//用户通过键盘输入一个表达式,计算机进行判读,如果是合法的表达式就按运算符的优先顺序
//给出结果,如果是非法的,就给出非法提示,并让用户重新输入。用户可以输入'#'号来表示
//表达式输入完成,也可以选择不输入。
//使用了两个栈:操作数栈和操作符栈来实现。并演示了操作过程中栈的变化。
//功能限制:
//不支持大数运算,运算符仅限'+' '-' '*' '/',另外支持括号'(' ')'。
//-----------------------------------------------------------------------------------
#include "Stack.h"
#include 
"Function.h"

void main()
ExpandedBlockStart.gifContractedBlock.gif
{
    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; //接下来是否需要读入数字
ExpandedSubBlockStart.gifContractedSubBlock.gif
    enum {NUMBER, OPERATOR, LEFT_BRACKET, RIGHT_BRACKET}State; //接下来不应读入类型(数字,操作符,括号)
    do
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        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)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            showStack(optr, opnd); 
            printf(
"Read character: %c\n", c);
            
if(c >= '0' && c <= '9')
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if(State == NUMBER)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    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 == '#')
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if(State == OPERATOR || needNum == TRUE)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    valid 
= FALSE; //如果当前不能是操作符,表达式非法
                    break;
                }

                needNum 
= TRUE; //操作符后要有数字与它相匹配
                State = RIGHT_BRACKET; //操作符之后不能是右括号
                GetTop_OPTR(optr, &e);                    
                
switch(Precede(e, c))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
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 == ')')
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if(c == '(')
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
if(State == LEFT_BRACKET)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        valid 
= FALSE; //如果当前不能是右括号,表达式非法
                        break;
                    }

                    waitingMatch
++;
                    Push_OPTR(
&optr, '(');
                    printf(
"Operation: Push_OPTR(&optr, '(')\n");
                    State 
= OPERATOR;//左括号之后不能是操作符
                }

                
else if(waitingMatch == 0 && c == ')')
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    valid 
= FALSE; //括号不匹配,表达式为非法
                    break;
                }

                
else if(waitingMatch > 0 && c == ')'//脱括号
ExpandedSubBlockStart.gifContractedSubBlock.gif
                {
                    
if(State == RIGHT_BRACKET)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        valid 
= FALSE; //如果当前不能是右括号,表达式非法
                        break;
                    }

                    State 
= NUMBER; //右括号之后不能是数字
                    GetTop_OPTR(optr, &e);
                    
while(e != '(')
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        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
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                valid 
= FALSE; //输入非法字符
                break;
            }

            c 
= str[++index]; //游标下移
        }

        
if(waitingMatch > 0 || needNum == TRUE) //存在未匹配的括号, 等待操作数
            valid = FALSE;
        GetTop_OPTR(optr, 
&e);
        
//做最后的运算,将栈中还没进行运算的内容做运算
        while(e != '#' && valid == TRUE)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            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:

ContractedBlock.gifExpandedBlockStart.gifCode
//-----------------------------------
//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
ExpandedBlockStart.gifContractedBlock.gif
{
    OperatorType 
*base//在栈构造之前和销毁之后,base的值为NULL
    OperatorType *top;  //栈顶指针
    int stacksize;  //当前已分配的存储空间,以元素为单位
}OPTRStack;

typedef 
struct
ExpandedBlockStart.gifContractedBlock.gif
{
    OperandType 
*base;
    OperandType 
*top;
    
int stacksize;
}
OPNDStack;

//初始化
Status InitStack_OPTR (OPTRStack *s)
ExpandedBlockStart.gifContractedBlock.gif
{
    (
*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)
ExpandedBlockStart.gifContractedBlock.gif
{
    (
*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)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(s.top == s.base)
       
return ERROR;
    
*= *(s.top-1);
    
return OK;
}


Status GetTop_OPND (OPNDStack s, OperandType 
*e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if(s.top == s.base)
       
return ERROR;
    
*= *(s.top-1);
    
return OK;
}

//进栈
Status Push_OPTR (OPTRStack *s, OperatorType e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top-(*s).base >= (*s).stacksize)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
       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)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top-(*s).base >= (*s).stacksize)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
       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)
ExpandedBlockStart.gifContractedBlock.gif
{
    
if((*s).top == (*s).basereturn ERROR;
    (
*s).top--*= *(*s).top;
    
return OK;
}


Status Pop_OPND (OPNDStack 
*s, OperandType *e)
ExpandedBlockStart.gifContractedBlock.gif
{
    
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值