顺序栈使用——表达式求值
2017-11-30 13:06
603 查看
顺序栈使用——表达式求值
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。欢迎大家阅读我的博客,如果有错误请指正,有问题请提问,我会尽我全力改正错误回答问题。在次谢谢大家。下面开始正式内容
顺序栈部分在之前已经在另一篇文章中提及,本篇中就不再提及,如有需要请阅读<顺序栈的各种基本运算>。
实验环境
语言c/c++编译器devc++5.11/5.40
实验内容与要求
问题描述:设一个算术表达式中包含圆括号、+、-、*、/、正整数,编写一个程序完成对表达式的求值运算。
目录
顺序栈使用——表达式求值实验环境
实验内容与要求
目录
实验解析
思路方法
定义说明
函数说明
流程图
运算函数
进行一步运算
进行一级运算
计算
主函数
结果展示
附录
相关资料
源代码
Stack.h
main.cpp
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
实验解析
思路方法
可以使用两个工作栈:一个栈OPTR存放运算符;
另一个栈OPND存放操作数;
用算符优先关系来判断相邻两个符号之间的优先关系。
定义说明
Stack num_stack 运算数栈 Stack opr_stack 操作符栈 double calculate(char *, Stack* ,Stack*);//核心运算部分 double get_result(double ,Stack* ,Stack*);//进行一步运算获取结果 double accumulate(Stack* ,Stack* );//
定义常用常量,类型别称
函数说明
流程图
Created with Raphaël 2.1.2初始化读取完毕?获取运算结果返回结果,程序结束读取数据进栈,乘除直接运算遇到"()"?运算"()"内数据"()"前有"*/"?运算一步乘除yesnoyesnoyesno运算函数
进行一步运算
double get_result(double right,Stack* num_stack,Stack* opr_stack){ double left=OutStack(*num_stack);//获取运算数 char oper=OutStack(*opr_stack);//获取操作 switch(oper){//根据运算符返回结果 case '+': return left+right; case '-': return left+right; case '*': return left*right; case '/': return left/right; } }
进行一步运算,返回结果。调用时注意栈是否为空,没有做安全防护
进行一级运算
double accumulate(Stack* num_stack,Stack* opr_stack){ double acc = OutStack(*num_stack); while(TopStack(*opr 10755 _stack)!='('&&EmptyStack(*num_stack)!=1){ acc= get_result(acc,num_stack, opr_stack); } if(EmptyStack(*num_stack)!=1){ OutStack(*opr_stack); //处理括号前为乘除的情况 if(TopStack(*opr_stack)==(int)'/'||TopStack(*opr_stack)==(int)'*'){ acc= get_result(acc,num_stack, opr_stack); }else if(TopStack(*opr_stack)==(int)'-') acc= -acc; } return acc; }
运算同一级
计算
double calculate(char *s, Stack* num_stack,Stack* opr_stack){ int i= 0; int j = 0;// 小数位数 int length = strlen(s); int flag =0 ; //判断 -1不运算取负数 0不运算 1进行一次运算 double tempnumber=0;//数字缓存 double spot=-0;//小数部分 while(i<length){ //数字 if(isdigit(s[i])){ tempnumber = (s[i]-'0');//字符转数字 while(i<length&&isdigit(s[i+1])){//多位数转换 tempnumber =tempnumber*10 +(s[++i]-'0'); } if(s[i+1]=='.'){//小数部分 i++; spot=-0; while(i<length&&isdigit(s[i+1])){ j++; spot =spot*10 +(s[++i]-'0'); } for(;j>0;j--){//转换小数部分 spot /=10; } tempnumber += spot;//合成一个数 } //运算数入栈 if(flag==-1){ flag = 0; PushStack(*num_stack,-tempnumber); }else if(flag == 0){//不进行运算 PushStack(*num_stack,tempnumber); }else if(flag == 1){//进行一次运算 flag =0; PushStack(*num_stack, get_result(tempnumber,num_stack,opr_stack)); } //如果当前字符是运算符. }else{ switch(s[i]){ case '+'://如果是加号. PushStack(*opr_stack,'+'); break; case '-'://如果是减号. flag = -1; PushStack(*opr_stack,'-'); break; //乘除法优先级高所以直接就运算掉 case '*'://如果是乘号. flag=1; PushStack(*opr_stack,'*'); break; case '/'://如果是除号. flag=1; PushStack(*opr_stack,'/'); break; //但是如果乘除后是括号就不能运算 case '('://如果是左括号. flag = 0; PushStack(*opr_stack, '('); break; case ')'://如果是右括号.这时获取这一级的结果,这时需要考虑括号前如果是乘除也需要运算掉。 //计算当前的栈内元素值. PushStack(*num_stack, accumulate(num_stack,opr_stack)); break; default:break; } } i++; } return accumulate(num_stack,opr_stack); }
运算同一级
主函数
int main(){ Stack num_stack; Stack opr_stack; InitList_stack(num_stack); InitList_stack(opr_stack); char s[100] = {0}; gets(s); printf("结果是:%f",calculate(s,&num_stack,&opr_stack)); return 0; }
结果展示
附录
相关资料
顺序栈的各种基本运算源代码
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。Stack.h
#include<stdio.h> //EOF,NULL #include<malloc.h> //malloc() #include<process.h> //exit() #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Status; typedef double SElemType; #define STACK_INIT_SIZE 100 //栈存储空间的初始分配量 #define STACKINCREMENT 10 //存储空间分配增量 typedef struct{ SElemType *base; //存储数据元素的数组 SElemType *top; //栈顶指针 int stacksize; //当前分配的栈空间大小 //(以sizeof(SElemType)为单位) }Stack; Status InitList_stack (Stack &s) { s.base = (SElemType*)malloc( STACK_INIT_SIZE*sizeof(SElemType)); if (!s.base ) exit(0); s.stacksize = STACK_INIT_SIZE; s.top = s.base; return OK; }// InitList_stack Status EmptyStack (Stack s) { if(s.base == s.top) return TRUE; else return FALSE; }// Status PushStack(Stack &s , SElemType e ){ if(s.stacksize<(s.top-s.base) )return ERROR; if(s.stacksize==(s.top-s.base) ) s.base = (SElemType*)malloc(( s.stacksize+STACKINCREMENT)*sizeof(SElemType)); *(s.top) = e; s.top++; return OK; } Status GetLength(Stack s){ return s.top-s.base; } Status DisplayStack(Stack &s){ while(s.base != s.top){ printf("%c ",*--(s.top)); } printf("\n"); } SElemType OutStack(Stack &s ){ SElemType e; if(s.top != s.base) e= *(--s.top); return e; } SElemType TopStack(Stack &s ){ SElemType e; if(s.top != s.base) e= *(s.top-1); return e; } Status DestroyStack ( Stack s) { if (!s.base) return ERROR; free (s.base); s.base = NULL; s.top = NULL; s.stacksize= 0; return OK; }// DestroyList_Sq
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
main.cpp
#include "Stack.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//函数声明
double calculate(char *, Stack* ,Stack*);
double get_result(double ,Stack* ,Stack*);
double accumulate(Stack* ,Stack* );
//运算
double calculate(char *s, Stack* num_stack,Stack* opr_stack){
int i= 0;
int j = 0;// 小数位数
int length = strlen(s);
int flag =0 ; //判断
double tempnumber=0;//数字缓存
double spot=-0;//小数部分
while(i<length){
if(isdigit(s[i])){//数字
tempnumber = (s[i]-'0');
while(i<length&&isdigit(s[i+1])){
tempnumber =tempnumber*10 +(s[++i]-'0');
}
if(s[i+1]=='.'){
i++;
spot=-0;
while(i<length&&isdigit(s[i+1])){
j++;
spot =spot*10 +(s[++i]-'0');
}
for(;j>0;j--){
spot /=10;
}
tempnumber += spot;
}
if(flag==-1){
flag = 0;
PushStack(*num_stack,-tempnumber);
}else if(flag == 0){//不进行运算
PushStack(*num_stack,tempnumber);
}else if(flag == 1){//进行一次运算
flag =0;
PushStack(*num_stack, get_result(tempnumber,num_stack,opr_stack));
}
}else{//如果当前字符是运算符.
switch(s[i]){
case '+'://如果是加号.
PushStack(*opr_stack,'+');
break;
case '-'://如果是减号.
flag = -1;
PushStack(*opr_stack,'-');
break;
case '*'://如果是乘号.
flag=1;
PushStack(*opr_stack,'*');
break;
case '/'://如果是除号.
flag=1;
PushStack(*opr_stack,'/');
break;
case '('://如果是左括号.
flag = 0;
PushStack(*opr_stack, '(');
break;
case ')'://如果是右括号.
//计算当前的栈内元素值.
PushStack(*num_stack, accumulate(num_stack,opr_stack));
break;
default:break;
}
}
i++;
}
return accumulate(num_stack,opr_stack);
}
double accumulate(Stack* num_stack,Stack* opr_stack){
double acc = OutStack(*num_stack);
while(TopStack(*opr_stack)!='('&&EmptyStack(*num_stack)!=1){
acc= get_result(acc,num_stack, opr_stack);
}
if(EmptyStack(*num_stack)!=1){
OutStack(*opr_stack);
if(TopStack(*opr_stack)==(int)'/'||TopStack(*opr_stack)==(int)'*'){
acc= get_result(acc,num_stack, opr_stack);
}else if(TopStack(*opr_stack)==(int)'-')
acc= -acc;
}
return acc;
}
double get_result(double right,Stack* num_stack,Stack* opr_stack){
double left=OutStack(*num_stack);
char oper=OutStack(*opr_stack);
switch(oper){
case '+':
return left+right;
case '-':
return left+right;
case '*':
return left*right;
case '/':
return left/right;
}
}
int main(){ Stack num_stack; Stack opr_stack; InitList_stack(num_stack); InitList_stack(opr_stack); char s[100] = {0}; gets(s); printf("结果是:%f",calculate(s,&num_stack,&opr_stack)); return 0; }
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
相关文章推荐
- 顺序栈实现表达式求值
- 第三章:顺序栈及其应用之一---表达式求值
- 表达式运算顺序与求值顺序,副作用操作符(++,--),序列点
- c语言表达式求值顺序
- 桟的使用之算术表达式求值
- C++ - 表达式求值顺序
- C,C++表达式求值顺序【推荐】
- c++表达式求值顺序
- ZT C,C++表达式求值顺序 裘老的解释。 [问题点数:300分]
- C,C++表达式求值顺序 裘老的解释。
- 【转载】关于C/C++ 表达式求值顺序
- C,C++表达式求值顺序
- C/C++ 语言中的表达式求值顺序
- C语言表达式求值顺序
- C,C++表达式中含++的求值顺序
- C/C++表达式求值顺序
- 关于C/C++ 表达式求值顺序 未定义(转)
- C,C++表达式中含++的求值顺序
- C,C++表达式求值顺序
- C语言 算数表达式求值(顺序栈应用实例)