数据结构-表达式的计算(栈)

栈----表达式的实现(顺序栈)

首先我们要知道中缀表达式和后缀表达式的含义

当然我们以人的视角觉得中缀表达式更适合计算,但是机器不是这么想的,相比于中缀表达式而言后缀表达式更容易被机器识别并进行计算
在这里插入图片描述
由于本人之前的数据结构的知识已经忘光了,所以用了一天的时间按照自己的理解把上述过程写了一遍 期间也遇到了许许多多的小问题,还有一些重要的功能没有完成,请大家谅解
不多说了,直接贴上代码!(有很多冗余代码。。。不好意思)
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以内的数字,做到最后心态崩了,然后也找不到什么解决方案,感觉基本的算法是懂了,健壮性的问题还是会发生!

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如果大家有什么更好的方法,欢迎大家来补充!

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值