**正文实现的功能:**把像(1+2*3)*2-4#的表达式算出来
参照逻辑:小甲鱼的数据结构、大话数据结构
整合了一些功能
1、栈表的初始化
#include <iostream>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#define MAXBUFFER 10
using namespace std;
typedef double ElemType;
//栈的结构体
typedef struct
{
ElemType *base;
ElemType *top;
int stackSize;
}sqStack;
//初始化栈
void InitStack(sqStack *s)
{
s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if (!s->base)
exit(0);
s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}
//压栈
void Push(sqStack *s, ElemType e)
{
// 栈满,追加空间,鱼油必须懂!
if (s->top - s->base >= s->stackSize)
{
s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
if (!s->base)
exit(0);
//s->top = s->base + s->stackSize;
//第一时间并没有添加如此多的元素,所以没必要
s->stackSize = s->stackSize + STACKINCREMENT;
}
*(s->top) = e; // 存放数据
s->top++;
}
//出栈
void Pop(sqStack *s, ElemType *e)
{
if (s->top == s->base)
return;
//*e = *--(s->top); // 将栈顶元素弹出并修改栈顶指针
*e =* (s->top-1);
s->top--;
}
//栈元素的长度
int StackLen(sqStack s)
{
return (s.top - s.base);
}
//遍历栈
void StackTraverse(sqStack s)
{
while (s.base != s.top)
{
s.top--;
printf("%.1f\n", *s.top);
}
}
2、后缀表达式
/*
返回值:计算之后的值
参数1:后缀表达式的字符串
参数2:栈表,可以用局部变量
*/
double GetValue(char* cSrc,sqStack s)
{
int j = 0; char a[10];int i=0;
ElemType c, d;
printf("请输入你的表达式\n");
while (cSrc[j] != '#') //判断结束符
{
while (int(cSrc[j]) <= 57 && int(cSrc[j]) >= 48)
{
a[i] = cSrc[j];
a[i + 1] = '\0'; //c++中字符串以字符‘\0’结尾,所以每个字符串都有额外一个字符的开销。
i++;
if (i > 10)
printf("输入长度超限");
j++;
if (cSrc[j] == ' ') //判断下一个是否是 空格(分离出数字)
{
Push(&s, atof(a));
printf("传入的数据\n");
StackTraverse(s);
i = 0;
break;
}
}
switch (cSrc[j])
{
case('+'):
Pop(&s, &c);
Pop(&s, &d);
Push(&s, c + d);
break;
case('-'):
Pop(&s, &c);
Pop(&s, &d);
Push(&s, d - c);
break;
case('*'):
Pop(&s, &c);
Pop(&s, &d);
Push(&s, d * c);
break;
case('/'):
Pop(&s, &c);
Pop(&s, &d);
if (c == 0)
{
printf("除数已经为0");
break;
}
Push(&s, d / c);
break;
default:
break;
}
j++;
}
Pop(&s, &c);
return c;
}
3、中缀表达式 转 后缀表达式
//返回值 可以用全局变量,也可以传一个字符指针作为参数
char* GetInfix(char* ch)
{
char s[100]; int i = 0;int j=0;
sqStack p; ElemType e;
InitStack(&p); //初始化栈
while (ch[i] != '#')
{
while (ch[i] >= '0' && ch[i] <= '9')
{
s[j] = ch[i];
j++;
i++;
if (ch[i]<'0' || ch[i]>'9')
{
s[j] = ' ';
j++;
}
}
//并列条件,先判断谁都行
if (')'==ch[i])
{
printf("存了多少个\n");
StackTraverse(p);
Pop(&p,&e);
while ('(' != char(e))
{
s[j] = char(e);
j++;
Pop(&p,&e);
}
}
else if ('+' == ch[i] || '-' == ch[i]) //权限最低,权限高的弹出
{
if (!StackLen(p)) //如果为空压栈
{
Push(&p, ch[i]);
}
else {
do {
Pop(&p, &e); //弹出元素
if ('(' == char(e))
{
Push(&p, e);//再次压入栈,为了上面的判断
}
else //之前的加减乘除弹出来
{
s[j] = char(e);
j++;
}
} while(StackLen(p) && '('!= char(e));
Push(&p, ch[i]);
}
}
else if ('*' == ch[i] || '/' == ch[i] || '(' == ch[i])
{
Push(&p, ch[i]);
}
else if ('#' == ch[i])
{
Pop(&p,&e);
s[j] = char(e);
j++;
s[j] = '#';
break;
}
else
{
printf("\n出错:输入格式错误!\n");
break;
}
i++;
}
return t;
}
4、主程序实现逻辑
int main()
{
sqStack s; char e;
ElemType c, d;
char a[10];
char chr;
int i = 0;
char ct[100];
InitStack(&s);
printf("请输入你的表达式");
int k = 0;
scanf("%c", &chr);
while (chr != '#')
{
ct[k] = chr;
k++;
scanf("%c", &chr);
}
ct[k] = '#';
k++;
strcpy(ct,GetInfix(ct));//必须这样
double t= GetValue(ct, s);
printf("已经运算完毕%.1f\n", t);
getchar();
return 0;
}
5、遇到的问题
1、返回值用 char*,只要不用strcpy得到的值便是乱码;
https://zhidao.baidu.com/question/14732048.html
解决方案:(1)将返回值作为形参传入(2) 用strcpy函数 (3)全局变量
2、注意细节逻辑
完整代码:链接:https://pan.baidu.com/s/1cTwVbTV07xHCcVASRgrwtA
提取码:mx17