表达式求值的C实现
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;
}
//-----------------------------------
//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);
}
//---------------------------------
//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;
}
//-----------------------------------
//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