码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
欢迎大家阅读我的博客,如果有错误请指正,有问题请提问,我会尽我全力改正错误回答问题。在次谢谢大家。下面开始正式内容
顺序栈部分在之前已经在另一篇文章中提及,本篇中就不再提及,如有需要请阅读<顺序栈的各种基本运算>。
问题描述:
设一个算术表达式中包含圆括号、+、-、*、/、正整数,编写一个程序完成对表达式的求值运算。
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
可以使用两个工作栈:
用算符优先关系来判断相邻两个符号之间的优先关系。
Stack num_stack 运算数栈
Stack opr_stack 操作符栈
double calculate(char *, Stack* ,Stack*);//核心运算部分
double get_result(double ,Stack* ,Stack*);//进行一步运算获取结果
double accumulate(Stack* ,Stack* );//
定义常用常量,类型别称
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_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//数字
if(isdigit(s[i])){
tempnumber = (s[i]-'0');//字符转数字
while(iisdigit(s[i+1])){//多位数转换
tempnumber =tempnumber*10 +(s[++i]-'0');
}
if(s[i+1]=='.'){//小数部分
i++;
spot=-0;
while(iisdigit(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;
}
- 顺序栈的各种基本运算
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
#include //EOF,NULL
#include //malloc()
#include //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
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。
#include "Stack.h"
#include
#include
#include
#include
//函数声明
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(iif(isdigit(s[i])){//数字
tempnumber = (s[i]-'0');
while(iisdigit(s[i+1])){
tempnumber =tempnumber*10 +(s[++i]-'0');
}
if(s[i+1]=='.'){
i++;
spot=-0;
while(iisdigit(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;
}
码文不易,如果帮助到您,希望您可以帮我刷一下点击量,与您无害,与我有益谢谢 支持原创 。