栈:只允许在一端进行插入和删除操作,(后进先出)
实现简单的四则运算 包括 +-*/以及()
参考博客: http://blog.csdn.net/zhaishaojiang/article/details/40017791
工程一共包含5个文件(由于代码不多,未分成头文件和实现)
1. OptrStack.h OptrStack.c 操作符栈 包含基本的栈结构定义和操作方法
2. OpndStack.h OpndStack.c 操作数栈 包含基本的栈结构定义和操作方法
3. main.c : 测试文件 包含运算的方法
定义两个栈分别用于存储操作符和操作数;
栈所具有的功能有:置栈空,判栈空,入栈,出栈,取栈顶;
将输入的算术表达式存入字符数组中;
将表达式中的运算符划分优先级;
进行双目运算,即+,-,*,/;
将表达式压入栈中,并计算表达式结果。(思路:将操作符压入操作符栈中,将操作数压入操作数栈中。过程:判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,再将当前的操作符压入操作符栈中。)
OpndStack.h
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE2 100
typedef struct
{
double date[MAXSIZE2];
int top;
}OpndStack; //操作数结构体
/*-------操作数相关操作-------*/
OpndStack *Init_OpndStack();/*置栈空*/
int Empty_OpndStack(OpndStack *t);/*判空栈*/
int Push_OpndStack(OpndStack *t, double y);/*入栈(注意:判断栈是否已满)*/
double Pop_OpndStack(OpndStack *t);/*出栈(注意:判断栈是否已空)*/
double GetTop_OpndStack(OpndStack *t);/*取栈顶元素*/
OpndStack.c
#include "OpndStack.h"
/*-------操作数相关操作-------*/
OpndStack *Init_OpndStack()/*置栈空*/
{
OpndStack *t;
t = (OpndStack *)malloc(sizeof(OpndStack));
t->top = -1;
return t;
}
int Empty_OpndStack(OpndStack *t)/*判空栈*/
{
if(t->top == -1)
{
return 1;
}
else
{
return 0;
}
}
int Push_OpndStack(OpndStack *t, double y)/*入栈(注意:判断栈是否已满)*/
{
if(t->top == MAXSIZE2 - 1)
{
return 0;
}
else
{
t->top ++;
t->date[t->top] = y;
return 1;
}
}
double Pop_OpndStack(OpndStack *t)/*出栈(注意:判断栈是否已空)*/
{
double y; //接收要出栈的元素
if( Empty_OpndStack(t) )
{
return 0;
}
y = t->date[t->top];
t->top --;
return y;
}
double GetTop_OpndStack(OpndStack *t)/*取栈顶元素*/
{
if( Empty_OpndStack(t) )
{
return 0;
}
else
{
return (t->date[t->top]);
}
}
OptrStack.h
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE1 100
typedef struct
{
char date[MAXSIZE1];
int top;
}OptrStack; //操作符结构体
/*-------操作符相关操作-------*/
OptrStack *Init_OptrStack(); /*置栈空*/
int Empty_OptrStack(OptrStack *s);/*判空栈*/
int Push_OptrStack(OptrStack *s, char x);/*入栈(注意:判断栈是否已满)*/
char Pop_OptrStack(OptrStack *s);/*出栈(注意:判断栈是否已空)*/
char GetTop_OptrStack(OptrStack *s);/*取栈顶元素,先判空*/
OptrStack.c
#include "OptrStack.h"
/*-------操作符相关操作-------*/
OptrStack *Init_OptrStack() /*置栈空*/
{
OptrStack *s;
s = (OptrStack *)malloc(sizeof(OptrStack));
s->top = -1;
return s;
}
int Empty_OptrStack(OptrStack *s)/*判空栈*/
{
if(s->top == -1)
{
return 1; //如果栈为空,则返回真数
}
else
{
return 0; //反之,返回零
}
}
int Push_OptrStack(OptrStack *s, char x)/*入栈(注意:判断栈是否已满)*/
{
if(s->top == MAXSIZE1 - 1)
{
return 0;
}
else
{
s->top ++; //栈顶指针向上移,再赋值
s->date[s->top] = x;
return 1;
}
}
char Pop_OptrStack(OptrStack *s)/*出栈(注意:判断栈是否已空)*/
{
int x; //接收要出栈的元素
if( Empty_OptrStack(s) )
{
return 0;
}
x = s->date[s->top];
s->top --;
return x;
}
char GetTop_OptrStack(OptrStack *s)/*取栈顶元素,先判空*/
{
if( Empty_OptrStack(s) )
{
return 0;
}
else
{
return (s->date[s->top]);
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "OpndStack.h"
#include "OptrStack.h"
int Rank(char op); //划分运算符的优先级
double Operate(double a, double b, char op); //运算操作
void Handle_str(char str[]); //将储存表达式的字符数组压入栈内,并运算
int main()
{
char str[100];
printf("请输入算术表达式(功能:+,-,*,/。可带括号!):\n");
scanf("%s", str);
Handle_str(str);
return 0;
}
int Rank(char op) //划分运算符的优先级
{
int x;
switch(op)
{
case '#':
x = 0;break;
case '(':
x = 1;break;
case '+':
case '-':
x = 2;break;
case '*':
case '/':
x = 3;break;
}
return x;
}
double Operate(double a, double b, char op) //运算操作
{
double c;
switch(op)
{
case '+':
c = a + b;break;
case '-':
c = a - b;break;
case '*':
c = a * b;break;
case '/':
if(b == 0)
{
printf("分母为零!\n");
return 0;
}
else
c = a / b;break;
default:
printf("输入的字符非法!\n");
break;
}
return c;
}
void Handle_str(char str[]) //将储存表达式的字符数组压入栈内
{
OptrStack *optr = Init_OptrStack(); //初始化操作符栈
OpndStack *opnd = Init_OpndStack(); //初始化操作数栈
int i,j; //i,j为循环变量,a,b接收从操作数栈中出栈的元素
double f,a,b; //接收将字符数转换为浮点数的值
char d[100]; //储存字符串中连续的‘数’
char op; //接收从操作符栈中出栈的元素
Push_OptrStack(optr, '#'); //先往操作符栈中压入'#'
for (i = 0; str[i]; i++)
{
switch(str[i]){
case '+':
case '-':
/*先判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;
小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,
再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,
再将当前的操作符压入操作符栈中。*/
if(GetTop_OptrStack(optr) == '#' || GetTop_OptrStack(optr) == '(')
{
Push_OptrStack(optr, str[i]);//入栈
}
else
{
a = Pop_OpndStack(opnd);//接收从操作数栈中出栈的元素
b = Pop_OpndStack(opnd);//接收从操作数栈中出栈的元素
op = Pop_OptrStack(optr);//接收从操作符栈中出栈的元素
Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中
Push_OptrStack(optr, str[i]);
}
break;
case '*':
case '/':
if(Rank(str[i]) > Rank(GetTop_OptrStack(optr)) || GetTop_OptrStack(optr) == '(')
{
Push_OptrStack(optr, str[i]);
}
else
{
a = Pop_OpndStack(opnd);
b = Pop_OpndStack(opnd);
op = Pop_OptrStack(optr);
Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中
Push_OptrStack(optr, str[i]);
}
break;
case '(':
Push_OptrStack(optr, str[i]);
break;
case ')':
while(GetTop_OptrStack(optr) != '(')
{
a = Pop_OpndStack(opnd);
b = Pop_OpndStack(opnd);
op = Pop_OptrStack(optr);
Push_OpndStack(opnd, Operate(b, a, op)); //将计算后的值压入操作数栈中
}
Pop_OptrStack(optr);
break;
default:
j=0;
do{
d[j++]=str[i];
i++;
}while(str[i]>='0' && str[i]<='9'|| str[i]=='.'); //可存入一个或多个数字字符
d[j]='\0'; //将输入的连续多个数字字符拼成了字符串
i--;
f=atof(d); //调用库函数atof()将字符数转换为浮点数
Push_OpndStack(opnd, f); //将转换后的数压入操作数栈中
break;
}
}
while(GetTop_OptrStack(optr) != '#')
{
a = Pop_OpndStack(opnd);
b = Pop_OpndStack(opnd);
op = Pop_OptrStack(optr);
Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中
}
printf("表达式%s = %g\n", str, GetTop_OpndStack(opnd));//将操作数栈中的元素(即表达式的最终结果)打印出来
}
个人博客 欢迎来访: http://ay2626.me