这里写目录标题
栈----表达式的实现(顺序栈)
首先我们要知道中缀表达式和后缀表达式的含义
当然我们以人的视角觉得中缀表达式更适合计算,但是机器不是这么想的,相比于中缀表达式而言后缀表达式更容易被机器识别并进行计算
由于本人之前的数据结构的知识已经忘光了,所以用了一天的时间按照自己的理解把上述过程写了一遍 期间也遇到了许许多多的小问题,还有一些重要的功能没有完成,请大家谅解
不多说了,直接贴上代码!(有很多冗余代码。。。不好意思)
Stack.h
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#define N 30
#define TRUE 1
#define FALSE 0
typedef char StackElementType;
typedef struct Stack
{
StackElementType elem[N];
int top;
}SeqStack;
void InitStack(SeqStack *S); //初始化
int Push(SeqStack *S,StackElementType s); //进栈
int Pop(SeqStack *S,StackElementType *s); //出栈
int GetTop(SeqStack *S,StackElementType *s); //与出栈不同,它不用移动top指针的位置
int StackPrint(SeqStack *S);
//中缀转化为后缀表达式
//两个栈表 一个存入操作数字 一个存入运算符
void Transmit(SeqStack *S,SeqStack *P,StackElementType s);
char Run(char num1,char num2,char x);
void Runmit(SeqStack *S,SeqStack *P);
int priority(char ch);//优先级比较函数
Stack.c
#include "Stack.h"
void InitStack(SeqStack *S) { //初始化
S->top = -1; //起始top指针指向-1
}
int Push(SeqStack *S, StackElementType s) { //进栈
if (S->top != N - 1) { //栈没有满的情况下
S->top++;
S->elem[S->top] = s;
// printf("%c",S->elem[S->top]);
}
return 0;
}
int Pop(SeqStack *S, StackElementType *s) { //出栈
if (S->top != -1) { //栈没有空的情况下
*s = S->elem[S->top];
S->top--;
}
return 0;
}
int GetTop(SeqStack *S, StackElementType *s) { //与出栈不同,它不用移动top指针的位置
*s = S->elem[S->top];
return 0;
}
int StackPrint(SeqStack *S) {
int i;
for (i = S->top; i>-1; i--)
printf("%c", S->elem[i]);
return 0;
}
//中缀转化为后缀表达式
void Transmit(SeqStack *S, SeqStack *P, StackElementType s) {
char s1, s2, s3; //接受数字字符 运算符
char ch;
if ('0' <= s&&s <= '9') {
Push(S, s);
}
else if (s == '(') {
Push(P, s);
}
else if (s == ')') {
while ((P->elem[P->top] != '(') && S->elem[S->top]) { //知道遇到(时 弹出所有运算符号
Pop(P, &s3);
Pop(S, &s1);
Pop(S, &s2);
ch = Run(s1, s2, s3);
Push(S, ch);
}
Pop(P, &s3);
}
else { //代表着是运算符
// printf("\n这里是运算符号");
if (priority(s)<=priority(P->elem[P->top])) {
Pop(P, &s3);
Pop(S, &s1);
Pop(S, &s2);
ch = Run(s1, s2, s3);
Push(S, ch);
}
Push(P, s);
}
}
//运算符号还有遗留符号未进行计算
void Runmit(SeqStack *S, SeqStack *P) {
char s1, s2, s3;
char ch;
while (P->top!=-1) {
Pop(P, &s3);
Pop(S, &s1);
Pop(S, &s2);
ch = Run(s1, s2, s3);
Push(S, ch);
}
}
//后缀表达式运算
char Run(char num1, char num2, char x) { //两个数字 一个运算符
int ch;
char c;
switch (x) {
case '+':
ch = (num1 - '0') + (num2 - '0');
break;
case '-':
ch = (num1 - '0') - (num2 - '0');
break;
case '*':
ch = (num1 - '0') *(num2 - '0');
break;
case '/':
ch = (num1 - '0') / (num2 - '0');
break;
}
return ch+'0'; //只能计算10以内的加减乘除
}
//优先级比较函数
int priority(char ch) {
int ret = 0;
switch (ch) {
case '+':
case '-':
ret = 1;
break;
case '*':
case '/':
ret = 2;
break;
default:
break;
}
return ret;
}
main.c
#include "Stack.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
int i;
char x ;
char str[N];
SeqStack *S,*P,s,p;
S=&s; //需要获取首地址
P=&p;
InitStack(S);
InitStack(P);
printf("请输入你要输入的运算字符串的:");
gets(str);
// scanf("%s",str); //与gets效果类似
printf("%s",str);
//计算你输入的表达式
// printf("\n%d",strlen(str));
for(i=0;i<strlen(str);i++)
{
Transmit(S,P,str[i]);
}
Runmit(S,P);
printf("\n%c",S->elem[S->top]);
//测试Stack栈功能
// for(i=0;i<3;i++)
// {
// scanf("%c",&x);
// Push(S,x);
// }
// StackPrint(S);
return 0;
}
很遗憾的就是后来我发现只能做个位数的运算,然后只能算10以内的数字,做到最后心态崩了,然后也找不到什么解决方案,感觉基本的算法是懂了,健壮性的问题还是会发生!
如果大家有什么更好的方法,欢迎大家来补充!