利用栈的原理计算一个表达式的值
来源:互联网 发布:java反射得到属性 编辑:程序博客网 时间:2024/06/01 16:34
#include<stdio.h>
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
/*计算整数表达式的值
*表达式必须以#结束
*表达式中可以出现多位数字,
*表达式中可以出现空格
*运算符包括+,-,*,/,(,)
*运算结果可以是多位整数,并以整数的形式返回
*/
typedef int SElemType;/*放入堆栈的元素的类型*/
/*判断输入的某个字符是否是运算符
*c表示输入的字符
*op数组中存放系统能识别的运算符
*/
Status in(char c,char op[]){
char *p; //指针,用于指向op数组
p=op; //将op数组的地址给p,数组中的数组名一般表示数组的头地址,只要知道了头地址那么就可以访问数组了。
while(*p != '\0'){ //当
if(c == *p)
return TRUE;
p++;
}
return FALSE;
}
/*比较两个运算符的优先级
*a,b中存放待比较的运算符
*'>'表示a>b
*'0'表示不可能出现的比较
*/
char Precede(char a, char b){
int i,j;
char pre[][7]={
/*运算符之间的优先级制作成一张表格*/
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}};
switch(a){
case '+': i=0; break;
case '-': i=1; break;
case '*': i=2; break;
case '/': i=3; break;
case '(': i=4; break;
case ')': i=5; break;
case '#': i=6; break;
}
switch(b){
case '+': j=0; break;
case '-': j=1; break;
case '*': j=2; break;
case '/': j=3; break;
case '(': j=4; break;
case ')': j=5; break;
case '#': j=6; break;
}
return pre[i][j];
}
/*进行实际的运算
*a,b中分别以整数的形式存放两个待运算的操作数
*thea中存放代表操作符的字符
*结果以整数的形式返回
*/
int Operate(int a, char thea, int b){
int i,j,result;
i=a; //a,b中分别以整数的形式存放两个待运算的操作数
j=b;
switch(thea) {
case '+': result = i + j; break; //加法运算
case '-': result = i - j; break; //减法运算
case '*': result = i * j; break; //乘法运算
case '/': result = i / j; break; //除法运算
}
return result;
}
/*从输入缓冲区中获得下一个整数或运算符,并通过n带回到主调函数
*返回值为1表示获得的是运算符
*返回值为0表示获得的是整形操作数
*/
int getNext(int *n){
char c;
*n=0;
while((c=getchar())==' '); /*跳过一个或多个空格*/
if(!isdigit(c)){ /*通过函数判断如果字符不是数字,那么只能是运算符*/
*n=c;
return 1;
}
do { /*能执行到该条语句,说明字符是数字,此处用循环获得连续的数字*/
*n=*n*10+(c-'0'); /*把连续的数字字符转换成相对应的整数*/
c=getchar();
} while(isdigit(c)); /*如果下一个字符是数字,进入下一轮循环*/
ungetc(c,stdin); /*新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区*/
return 0;
}
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//构造一个空栈
Status InitStack(SqStack *S){
S->base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S->base)
printf("OVERFLOW");// exit(OVERFLOW);
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
return OK;
}
//判断是否为空栈
Status StackEmpty(SqStack S){
if(S.top == S.base)
return TRUE;
else
return FALSE;
}
//用e返回S的顶元素
Status GetTop(SqStack S, SElemType *e){
if(S.top == S.base)
return ERROR;
*e = *(S.top-1);
return OK;
}
//插入e为新的顶元素
Status Push(SqStack *S, SElemType e){
if((S->top - S->base) >= S->stacksize){
S->base = (
SElemType*)realloc(S->base,
(S->stacksize+STACKINCREMENT)*sizeof(SElemType)
);
if(!S->base)
return ERROR;// exit(OVERFLOW);
S->top = S->base +S->stacksize;
S->stacksize += STACKINCREMENT;
}
*(S->top)=e;
S->top++;
return OK;
}
//删除S的顶元素,并用e返回其值
Status Pop(SqStack *S, SElemType *e){
if(S->top == S->base)
return ERROR;
S->top--;
*e = *(S->top);
return OK;
}
//从栈底到栈顶依次对S的每个元素调用函数Visit(),一旦失败操作无效
Status ListTraverse(SqStack S,Status (*visit)(SElemType)){
SElemType *p;
p=S.base;
for(p=S.base;p<S.top;p++)
(*visit)(*p);
return OK;
}
//输出元素e
Status output(SElemType e){
printf("%d ",e);
return OK;
}
int EvaluateExpression()//操作函数
{
// int n;
int flag; //0,1标志
int c;
SElemType x,thea;
int a,b;
char OP[]="+-*/()#";
SqStack OPTR;
SqStack OPND;
InitStack(&OPTR);//构造空栈
Push(&OPTR,'#'); //元素入栈
InitStack(&OPND);
flag=getNext(&c);//调用getNext函数
GetTop(OPTR,&x); //调用GetTop函数,获得栈顶元素值给x
while(c!='#' || x != '#') //当c不是结束标志并且x也不是结束标识时
{
if(flag == 0)
{
Push(&OPND,c); //调用Push函数,新元素入栈
flag = getNext(&c); //调用getNext函数
} else
{
GetTop(OPTR, &x); //调用GetTop函数,获得栈顶元素值给x
switch(Precede(x,c))
{
case '<'://栈顶元素优先级低
Push(&OPTR,c);
flag = getNext(&c);
break;
case '='://脱括号并接受下一字符
Pop(&OPTR,&x);
flag = getNext(&c);
break;
case '>':// 退栈并将运算结果入栈
Pop(&OPTR, &thea);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND, Operate(a, thea, b));
break;
}
}
GetTop(OPTR, &x);
}
GetTop(OPND, &c);
return c; //返回值c
}
void main(){
int c;
printf("请输入您想输入的符号或数字:");
c=EvaluateExpression(); //调用EvaluateExpression函数
printf("计算结果=%d\n",c); //输出c
fflush(stdin);//以下这两个函数是为了解决程序有时闪屏而用的
getchar();
}
#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
/*计算整数表达式的值
*表达式必须以#结束
*表达式中可以出现多位数字,
*表达式中可以出现空格
*运算符包括+,-,*,/,(,)
*运算结果可以是多位整数,并以整数的形式返回
*/
typedef int SElemType;/*放入堆栈的元素的类型*/
/*判断输入的某个字符是否是运算符
*c表示输入的字符
*op数组中存放系统能识别的运算符
*/
Status in(char c,char op[]){
char *p; //指针,用于指向op数组
p=op; //将op数组的地址给p,数组中的数组名一般表示数组的头地址,只要知道了头地址那么就可以访问数组了。
while(*p != '\0'){ //当
if(c == *p)
return TRUE;
p++;
}
return FALSE;
}
/*比较两个运算符的优先级
*a,b中存放待比较的运算符
*'>'表示a>b
*'0'表示不可能出现的比较
*/
char Precede(char a, char b){
int i,j;
char pre[][7]={
/*运算符之间的优先级制作成一张表格*/
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}};
switch(a){
case '+': i=0; break;
case '-': i=1; break;
case '*': i=2; break;
case '/': i=3; break;
case '(': i=4; break;
case ')': i=5; break;
case '#': i=6; break;
}
switch(b){
case '+': j=0; break;
case '-': j=1; break;
case '*': j=2; break;
case '/': j=3; break;
case '(': j=4; break;
case ')': j=5; break;
case '#': j=6; break;
}
return pre[i][j];
}
/*进行实际的运算
*a,b中分别以整数的形式存放两个待运算的操作数
*thea中存放代表操作符的字符
*结果以整数的形式返回
*/
int Operate(int a, char thea, int b){
int i,j,result;
i=a; //a,b中分别以整数的形式存放两个待运算的操作数
j=b;
switch(thea) {
case '+': result = i + j; break; //加法运算
case '-': result = i - j; break; //减法运算
case '*': result = i * j; break; //乘法运算
case '/': result = i / j; break; //除法运算
}
return result;
}
/*从输入缓冲区中获得下一个整数或运算符,并通过n带回到主调函数
*返回值为1表示获得的是运算符
*返回值为0表示获得的是整形操作数
*/
int getNext(int *n){
char c;
*n=0;
while((c=getchar())==' '); /*跳过一个或多个空格*/
if(!isdigit(c)){ /*通过函数判断如果字符不是数字,那么只能是运算符*/
*n=c;
return 1;
}
do { /*能执行到该条语句,说明字符是数字,此处用循环获得连续的数字*/
*n=*n*10+(c-'0'); /*把连续的数字字符转换成相对应的整数*/
c=getchar();
} while(isdigit(c)); /*如果下一个字符是数字,进入下一轮循环*/
ungetc(c,stdin); /*新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区*/
return 0;
}
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//构造一个空栈
Status InitStack(SqStack *S){
S->base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S->base)
printf("OVERFLOW");// exit(OVERFLOW);
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;
return OK;
}
//判断是否为空栈
Status StackEmpty(SqStack S){
if(S.top == S.base)
return TRUE;
else
return FALSE;
}
//用e返回S的顶元素
Status GetTop(SqStack S, SElemType *e){
if(S.top == S.base)
return ERROR;
*e = *(S.top-1);
return OK;
}
//插入e为新的顶元素
Status Push(SqStack *S, SElemType e){
if((S->top - S->base) >= S->stacksize){
S->base = (
SElemType*)realloc(S->base,
(S->stacksize+STACKINCREMENT)*sizeof(SElemType)
);
if(!S->base)
return ERROR;// exit(OVERFLOW);
S->top = S->base +S->stacksize;
S->stacksize += STACKINCREMENT;
}
*(S->top)=e;
S->top++;
return OK;
}
//删除S的顶元素,并用e返回其值
Status Pop(SqStack *S, SElemType *e){
if(S->top == S->base)
return ERROR;
S->top--;
*e = *(S->top);
return OK;
}
//从栈底到栈顶依次对S的每个元素调用函数Visit(),一旦失败操作无效
Status ListTraverse(SqStack S,Status (*visit)(SElemType)){
SElemType *p;
p=S.base;
for(p=S.base;p<S.top;p++)
(*visit)(*p);
return OK;
}
//输出元素e
Status output(SElemType e){
printf("%d ",e);
return OK;
}
int EvaluateExpression()//操作函数
{
// int n;
int flag; //0,1标志
int c;
SElemType x,thea;
int a,b;
char OP[]="+-*/()#";
SqStack OPTR;
SqStack OPND;
InitStack(&OPTR);//构造空栈
Push(&OPTR,'#'); //元素入栈
InitStack(&OPND);
flag=getNext(&c);//调用getNext函数
GetTop(OPTR,&x); //调用GetTop函数,获得栈顶元素值给x
while(c!='#' || x != '#') //当c不是结束标志并且x也不是结束标识时
{
if(flag == 0)
{
Push(&OPND,c); //调用Push函数,新元素入栈
flag = getNext(&c); //调用getNext函数
} else
{
GetTop(OPTR, &x); //调用GetTop函数,获得栈顶元素值给x
switch(Precede(x,c))
{
case '<'://栈顶元素优先级低
Push(&OPTR,c);
flag = getNext(&c);
break;
case '='://脱括号并接受下一字符
Pop(&OPTR,&x);
flag = getNext(&c);
break;
case '>':// 退栈并将运算结果入栈
Pop(&OPTR, &thea);
Pop(&OPND,&b);
Pop(&OPND,&a);
Push(&OPND, Operate(a, thea, b));
break;
}
}
GetTop(OPTR, &x);
}
GetTop(OPND, &c);
return c; //返回值c
}
void main(){
int c;
printf("请输入您想输入的符号或数字:");
c=EvaluateExpression(); //调用EvaluateExpression函数
printf("计算结果=%d\n",c); //输出c
fflush(stdin);//以下这两个函数是为了解决程序有时闪屏而用的
getchar();
}
0 0
- 利用栈的原理计算一个表达式的值
- 利用栈计算表达式的值
- 利用栈计算算数表达式的值
- 利用栈计算表达式的值
- 利用正则表达式计算表达式的值
- 用数组创建一个栈(stack),并利用栈来计算后缀表达式的值
- 计算一个表达式的值
- 计算一个表达式的值
- 计算一个表达式的值
- 计算一个表达式的值
- 利用正则式计算表达式的值
- 利用栈结构计算代数表达式的值
- 利用栈计算表达式的值 By Assassin
- javascript 计算一个字符串表达式的值
- 利用表达式树,计算一个加减乘除(可带括号)的表达式
- 如何用栈计算一个算术表达式的值?
- 完全利用栈实现表达式的计算问题
- 利用API 实现字符串表达式的计算
- STL算法库-非修改序列式操作(一)
- Tomcat部署Web应用
- SAXParseException; lineNumber: 21; columnNumber: 7; 元素类型为 "set" 的内容必须匹配 "(met
- iis7 发布mvc 遇到的HTTP错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容
- Leetcode190: Game of Life
- 利用栈的原理计算一个表达式的值
- leetcode Excel Sheet Column Title
- 这两天都忘了写了,养成一个习惯真不容易
- MyEclipse与heidiMysql
- NuGet发布
- Python——迭代器和解析(2)
- Maven 每次update之后自动修改jdk问题
- 瀑布流-UICollectionView 的从新布局,动态加载HTML数据,HTML数据的解析和UICollectionViewFlowLayout的从布
- Unity 协程与线程区别