数据结构之---C语言实现栈的表达式求值(表达式树)
2015-09-20 22:44
603 查看
利用栈实现表达式树这里我一共有两种思路:
part one:
首先判断输入表达式的每个字符,如果遇到运算符,不压栈,
接着弹出两个栈顶的元素,进行元素,接着把结果压栈。
代码:
part two:
就是把所有输入压栈,分别有运算符栈和运算值栈,然后弹出一个运算符,
弹出两个运算值,进行运算,结果再压栈。
代码:(C++版本)
结果:
part one:
首先判断输入表达式的每个字符,如果遇到运算符,不压栈,
接着弹出两个栈顶的元素,进行元素,接着把结果压栈。
代码:
//栈实现表达式 //思路:此程序的思路是,读取输入的字符串,然后判断每个字符, //当遇到的是运算符,这时运算符不如栈,接着把栈顶的两个元素 //出栈,然后运算,然后再将得的结果压栈 //杨鑫 #include <stdio.h> #include <stdlib.h> typedef int SElemType; // 栈的元素类型 #define STACK_INIT_SIZE 10 // 存储空间初始分配量 #define STACKINCREMENT 2 // 存储空间分配增量 /* *顺序栈的结构体 * */ typedef struct SqStack { SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素为单位 }SqStack; /* *构造一个栈 * */ int InitStack(SqStack *S) { // 为栈底分配一个指定大小的存储空间 (*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if( !(*S).base ) exit(0); // 存储分配失败 (*S).top = (*S).base; // 栈底与栈顶相同表示一个空栈 (*S).stacksize = STACK_INIT_SIZE; return 1; } /* *获取栈顶元素 * */ int GetTop(SqStack S,SElemType *e) { if(S.top > S.base) { *e = *(S.top-1); // 栈顶指针的下一个位置为栈顶元素 return 1; } else return 0; } /* *入栈(压栈) * */ int 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 ) exit(0); // 存储分配失败 (*S).top = (*S).base+(*S).stacksize; (*S).stacksize += STACKINCREMENT; } *((*S).top)++=e; // 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左 return 1; } /* *出栈 * */ int Pop(SqStack *S,SElemType *e) { if((*S).top == (*S).base) return 0; *e = *--(*S).top; // 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左 return 1; } /* *判断优先级 * */ SElemType Precede(SElemType t1,SElemType t2) { SElemType f; switch(t2) { case '+': case '-': if(t1=='('||t1=='#') f='<'; else f='>'; break; case '*': case '/': if(t1=='*'||t1=='/'||t1==')') f='>'; else f='<'; break; case '(': if(t1==')') { printf("ERROR1\n"); exit(0); } else f='<'; break; case ')': switch(t1) { case '(': f='='; break; case '#': printf("ERROR2\n"); exit(0); default: f='>'; } break; case '#': switch(t1) { case '#': f='='; break; case '(': printf("ERROR3\n"); exit(0); default: f='>'; } } return f; } /* *搜索运算符 * */ int In(SElemType c) { switch(c) { case'+': case'-': case'*': case'/': case'(': case')': case'#':return 1; default:return 0; } } /* *运算 * */ SElemType Operate(SElemType a,SElemType theta,SElemType b) { SElemType c; a=a-48; //ASCII值转化为对应的十进制值 b=b-48; //ASCII值转化为对应的十进制值 switch(theta) { case'+': c=a+b+48; break; case'-': c=a-b+48; break; case'*': c=a*b+48; break; case'/':c=a/b+48; } return c; } /* *比较运算符优先级 * */ SElemType EvaluateExpression() { SqStack OPTR,OPND; SElemType a,b,c,x,theta; InitStack(&OPTR); Push(&OPTR,'#'); InitStack(&OPND); c=getchar(); GetTop(OPTR,&x); while(c!='#'||x!='#') { if(In(c)) // 是7种运算符之一 switch(Precede(x,c)) { case'<': Push(&OPTR,c); // 栈顶元素优先权低 c=getchar(); break; case'=': Pop(&OPTR,&x); // 脱括号并接收下一字符 c=getchar(); break; case'>': Pop(&OPTR,&theta); // 退栈并将运算结果入栈 Pop(&OPND,&b); Pop(&OPND,&a); Push(&OPND,Operate(a,theta,b)); break; } else if(c>='0'&&c<='9') // c是操作数 { Push(&OPND,c); c=getchar(); } else // c是非法字符 { printf("非法字符!!\n"); exit(0); } GetTop(OPTR,&x); } GetTop(OPND,&x); return x; } int main() { printf("请输入算术表达式,并以#结束\n"); printf("例如:3*(7-5)#\n"); printf("%c\n",EvaluateExpression()); return 0; }结果:
part two:
就是把所有输入压栈,分别有运算符栈和运算值栈,然后弹出一个运算符,
弹出两个运算值,进行运算,结果再压栈。
代码:(C++版本)
//栈实现表达式求和 //利用栈实现表达式运算 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define true 1 #define false 0 #define OPSETSIZE 8 typedef int Status; unsigned char Prior[8][8] = { // 运算符优先级表 // '+' '-' '*' '/' '(' ')' '#' '^' /*'+'*/'>','>','<','<','<','>','>','<', /*'-'*/'>','>','<','<','<','>','>','<', /*'*'*/'>','>','>','>','<','>','>','<', /*'/'*/'>','>','>','>','<','>','>','<', /*'('*/'<','<','<','<','<','=',' ','<', /*')'*/'>','>','>','>',' ','>','>','>', /*'#'*/'<','<','<','<','<',' ','=','<', /*'^'*/'>','>','>','>','<','>','>','>' }; typedef struct StackChar { char c; struct StackChar *next; }SC; //StackChar类型的结点SC typedef struct StackFloat { float f; struct StackFloat *next; }SF; //StackFloat类型的结点SF SC *Push(SC *s,char c) //SC类型的指针Push,返回p { SC *p=(SC*)malloc(sizeof(SC)); p->c=c; p->next=s; return p; } SF *Push(SF *s,float f) //SF类型的指针Push,返回p { SF *p=(SF*)malloc(sizeof(SF)); p->f=f; p->next=s; return p; } SC *Pop(SC *s) //SC类型的指针Pop { SC *q=s; s=s->next; free(q); return s; } SF *Pop(SF *s) //SF类型的指针Pop { SF *q=s; s=s->next; free(q); return s; } float Operate(float a,unsigned char theta, float b) //计算函数Operate { switch(theta) { case '+': return a+b; case '-': return a-b; case '*': return a*b; case '/': return a/b; case '^': return pow(a,b); default : return 0; } } char OPSET[OPSETSIZE]={'+','-','*','/','(',')','#','^'}; Status In(char Test,char *TestOp) { int Find=false; for (int i=0; i< OPSETSIZE; i++) { if(Test == TestOp[i]) Find= true; } return Find; } Status ReturnOpOrd(char op,char *TestOp) { for(int i=0; i< OPSETSIZE; i++) { if (op == TestOp[i]) return i; } } char precede(char Aop, char Bop) { return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)]; } float EvaluateExpression(char* MyExpression) { // 算术表达式求值的算符优先算法 // 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合 SC *OPTR=NULL; // 运算符栈,字符元素 SF *OPND=NULL; // 运算数栈,实数元素 char TempData[20]; float Data,a,b; char theta,*c,Dr[]={'#','\0'}; OPTR=Push(OPTR,'#'); c=strcat(MyExpression,Dr); strcpy(TempData,"\0");//字符串拷贝函数 while (*c!= '#' || OPTR->c!='#') { if (!In(*c, OPSET)) { Dr[0]=*c; strcat(TempData,Dr); //字符串连接函数 c++; if (In(*c, OPSET)) { Data=atof(TempData); //字符串转换函数(double) OPND=Push(OPND, Data); strcpy(TempData,"\0"); } } else // 不是运算符则进栈 { switch (precede(OPTR->c, *c)) { case '<': // 栈顶元素优先级低 OPTR=Push(OPTR, *c); c++; break; case '=': // 脱括号并接收下一字符 OPTR=Pop(OPTR); c++; break; case '>': // 退栈并将运算结果入栈 theta=OPTR->c;OPTR=Pop(OPTR); b=OPND->f;OPND=Pop(OPND); a=OPND->f;OPND=Pop(OPND); OPND=Push(OPND, Operate(a, theta, b)); break; } //switch } } //while return OPND->f; } //EvaluateExpression int main(void) { char s[128]; puts("请输入表达式:"); gets(s); puts("该表达式的值为:"); printf("%s\b=%g\n",s,EvaluateExpression(s)); system("pause"); return 0; }
结果:
相关文章推荐
- 算法数据结构之贪心算法
- 算法库应用——删除元素在[x, y]之间的元素
- 数据结构学习---链表的若干操作
- 数据结构学习---链表的若干操作
- 研磨数据结构与算法-12遍历二叉树
- 研磨数据结构与算法-11二叉树的基本操作
- 二叉树的创建、遍历、高度 例子
- 顺序表的基本操作(创建,遍历,查找,删除,归并)
- 数据结构--堆的实现(下)
- 【数据结构之旅】顺序栈的定义、初始化、空栈判断、入栈、出栈操作
- 【数据结构之旅】顺序栈的定义、初始化、空栈判断、入栈、出栈操作
- 研磨数据结构与算法-10二叉树的基本概念
- 研磨数据结构与算法-09快速排序
- 研磨数据结构与算法-08希尔排序
- 研磨数据结构与算法-07递归之高级应用
- 研磨数据结构与算法-06递归的应用
- 数据结构(C达到)------- 双链表
- 数据结构实践——后缀表达式(栈)
- 编程中最没用的东西是源代码,最有用的东西是算法和数据结构。
- 数据结构-线性表-栈