源代码提供
一. 头文件包含以及函数接口声明
- 首先要定义一个数据为double类型的栈来存放操作数,再定义一个字符类型的栈来存放运算符。
- 可以创建一个.h的头文件来存放如下的代码.
Stack.h代码如下
//第一步头文件包含
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<stdbool.h>
//第二步数据类型定义,栈的定义
typedef double DataType1;
typedef struct Stack1
{
DataType1* a;
int top;
int capacity;
}SeqStack1;
typedef char DataType2;
typedef struct Stack2
{
DataType2* a;
int top;
int capacity;
}SeqStack2;
//第三步接口函数的声明
void InitStack1(SeqStack1* ps);
void DestroyStack1(SeqStack1* ps);
void PushStack1(SeqStack1* ps, DataType1 x);
DataType1 PopStack1(SeqStack1* ps);
DataType1 GetTop1(SeqStack1* ps);
bool EmptyStack1(SeqStack1* ps);
void InitStack2(SeqStack2* ps);
void DestroyStack2(SeqStack2* ps);
void PushStack2(SeqStack2* ps, DataType2 x);
DataType2 PopStack2(SeqStack2* ps);
DataType2 GetTop2(SeqStack2* ps);
bool EmptyStack2(SeqStack2* ps);
二. 函数接口实现
- 判断字符是运算符还是操作数符
- 比较运算符优先级
- 计算表达式
Stack.c代码如下:
#include"Stack.h"
//接口函数定义实现
//初始化栈
void InitStack1(SeqStack1* ps)
{
assert(ps);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//销毁栈
void DestroyStack1(SeqStack1* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//压栈
void PushStack1(SeqStack1* ps, DataType1 x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
DataType1* tmp = realloc(ps->a, sizeof(DataType1) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail!\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
//出栈并返回栈顶元素
DataType1 PopStack1(SeqStack1* ps)
{
assert(ps);
assert(!EmptyStack1(ps));
DataType1 e = ps->a[ps->top - 1];
ps->top--;
return e;
}
//返回栈顶元素
DataType1 GetTop1(SeqStack1* ps)
{
assert(ps);
assert(!EmptyStack1(ps));
return ps->a[ps->top - 1];
}
//判断栈是否为空
bool EmptyStack1(SeqStack1* ps)
{
assert(ps);
return ps->top == 0;
}
//运算符栈
//初始化栈
void InitStack2(SeqStack2* ps)
{
assert(ps);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//销毁栈
void DestroyStack2(SeqStack2* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//压栈
void PushStack2(SeqStack2* ps, DataType2 x)
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
DataType2* tmp = realloc(ps->a, sizeof(DataType2) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail!\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
//出栈并返回栈顶元素
DataType2 PopStack2(SeqStack2* ps)
{
assert(ps);
assert(!EmptyStack2(ps));
DataType2 e = ps->a[ps->top - 1];
ps->top--;
return e;
}
//返回栈顶元素
DataType2 GetTop2(SeqStack2* ps)
{
assert(ps);
assert(!EmptyStack2(ps));
return ps->a[ps->top - 1];
}
//判断栈是否为空
bool EmptyStack2(SeqStack2* ps)
{
assert(ps);
return ps->top == 0;
}
//求值函数接口实现
//判断e是否是字符
int In(char e)
{
char number[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
for (int i = 0; i <= 9; i++)
{
if (number[i] == e)
return 1;
}
return 0;
}
//比较两运算符优先级
char Precede(char a, char b)
{
if (b == '+' || b == '-')
{
if (a == '(' || a == '#')
return '<';
else
return '>';
}
if (b == '*' || b == '/')
{
if (a == '*' || a == '/' || a == ')')
return '>';
else
return '<';
}
if (b == '(')
return '<';
if (b == ')')
{
if (a != '(')
return '>';
else
return '=';
}
if (b == '#')
{
if (a == '#')
return '=';
else
return '>';
}
}
//计算表达式
double Operate(double a, char theta, double b)
{
if (theta == '*')
return b * a;
if (theta == '/')
return b / a;
if (theta == '+')
return b + a;
if (theta == '-')
return b - a;
}
三. 测试程序
#include"Stack.h"
double EvualuateExpression()
{
SeqStack1 s1;
SeqStack2 s2;
InitStack1(&s1);
InitStack2(&s2);
PushStack2(&s2, ‘#’);
double a, b;
char e, theta;
e = getchar();
int flag = 0;
while (e != ‘#’ || GetTop2(&s2) != ‘#’)
{
if (e == ‘\n’)
break;
if (In(e) == 1)
{
e = e - ‘0’;
if (flag == 1)
{
double tmp = PopStack1(&s1);
tmp = 10 * tmp + e;
PushStack1(&s1, tmp);
}
else
{
PushStack1(&s1, e);
flag = 1;
}
e = getchar();
}
else
{
switch (Precede(GetTop2(&s2), e))
{
case ‘<’:
PushStack2(&s2, e);
e = getchar();
break;
case ‘>’:
a = PopStack1(&s1);
b = PopStack1(&s1);
theta = PopStack2(&s2);
PushStack1(&s1, Operate(a, theta, b));
break;
case ‘=’:
PopStack2(&s2);
e = getchar();
break;
}
}
}
return GetTop1(&s1);
}
int main()
{
printf(“请输入算术表达式(以#结束):\n”);
double ret = EvualuateExpression();
printf(“计算结果是:”);
printf(“%0.lf”, ret);
return 0;
}
觉得源代码对你有帮助的话,点个小赞,谢谢!