表达式求值之栈的运用

分析:由于要求用C语言编写,栈的操作我不知道C里面有没有库函数,所以直接将书上代码打下来单独用了一个头文件,代码如下:
PS:由于定义栈的存储类型不可变,除非再定义另外一个栈,比较麻烦,我将运算符也存在double栈中,添加一个运算符(char)转double子函数对其处理,±*/等分别对应一个数。

创建一个SeqStack.h头文件存顺序栈的操作,代码如下:

#ifndef _SEQSTACK_H_
#define _SEQSTACK_H_

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
#define DataType double

typedef struct
{	/*顺序栈*/
	DataType data[MAXSIZE];
	int top;
}SeqStack, *PSeqStack;

PSeqStack Init_SeqStack()
{	/*1.初始化空栈*/
	PSeqStack S = (PSeqStack)malloc(sizeof(SeqStack));
	if(S) S->top = -1;
	return S;
}

int Empty_SeqStack(PSeqStack S)
{	/*2.判栈空*/
	return (S->top == -1);
}

int Push_SeqStack(PSeqStack S, DataType x)
{	/*3.入栈*/
	if(S->top == MAXSIZE -1) return 0;		//栈满不能插入 
	else
	{
		S->data[++S->top] = x;
		return 1; 
	}
}

int Pop_SeqStack(PSeqStack S, DataType *x)
{	/*4.出栈*/
	if(Empty_SeqStack(S)) return 0;			//栈空不能出栈
	else
	{
		*x = S->data[S->top];				//用指针的方式取出栈中元素给x 
		S->top--;
		return 1;
	}
}

int GetTop_SeqStack(PSeqStack S, DataType *x)
{	/*5.取栈顶元素*/
	if(Empty_SeqStack(S)) return 0;			//栈空
	else
	{
		*x = S->data[S->top];				//用指针的方式将栈顶元素存入x中
		return 1;
	}
}

void Destroy_SeqStack(PSeqStack *S)
{	/*6.销毁栈*/
	if(*S) free(*S);
	*S = NULL;
	return;
}

#endif

创建一个priority.h头文件,代码如下:

#ifndef _PRIORITY_H_
#define _PRIORITY_H_

//求运算符优先级
int priority(double o)
{
	switch((int)o)
	{
		case 0: return 0;
		case 5: return 1;
		case 1:
		case 2: return 2;
		case 3:
		case 4: return 3;
	}
}

//判断是否为运算符 
int isOperator(char c)
{
	if(c == '+' || c == '-' || c == '*' || c == '/') return 1;
	else if(c == '(') return 2;
	else if(c == ')') return 3;
	else return 0;
}

//判断是否为数字
int isNum(char c)
{
	if(c >= '0' && c <= '9') return 1;
	else return 0;
}

//运算符转double
double operatorToDouble(char c)
{
	switch(c)
	{
		case '+': return 1;
		case '-': return 2;
		case '*': return 3;
		case '/': return 4;
		case '(': return 5;
		default: return 0;
	}
}

#endif

创建一个main.c文件,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "SeqStack.h"
#include "priority.h"

PSeqStack num;						//数字栈 
PSeqStack op;						//字符栈 
char s[512], *ps = s;				//输入的字符串和遍历该字符串的指针 
double x, o, y;						//x,y:两数字, o:运算符的double形式 
int flag = 0;						//0:当前运算不在括号内, 1:当前运算在括号内 

//字符串转double
void doNum()
{
	char numTemp[32];				//字符串转double的临时字符型数组 
	int i;							//下标,索引,遍历介质 
	memset(numTemp, 0, sizeof(numTemp));
	i = 0;
	if(*ps == '-') numTemp[i++] = *(ps++);
	while(isNum(*ps))
	{
		numTemp[i] = *ps;
		i++, ps++;
	}
	if(*ps == '.')
	{
		numTemp[i++] = '.';
		ps++;
		while(isNum(*ps))	//小数部分 
		{
			numTemp[i] = *ps;
			i++, ps++;
		}
	}
	Push_SeqStack(num, atof(numTemp));
}

void doOperator()
{
	Pop_SeqStack(num, &y);
	Pop_SeqStack(num, &x);
	Pop_SeqStack(op, &o);
	switch((int)o)
	{
		case 1: Push_SeqStack(num, x+y); break;
		case 2: Push_SeqStack(num, x-y); break;
		case 3: Push_SeqStack(num, x*y); break;
		case 4: Push_SeqStack(num, x/y); break;
	}
}

int main()
{
	num = Init_SeqStack();
	op = Init_SeqStack();
	memset(s, 0, sizeof(s));
	gets(s);
	int leftKH = 0, rightKH = 0;
	
	while(*ps)
	{
		if(*ps == '(') leftKH++;
		else if(*ps == ')') rightKH++;
		ps++;
	}
	if(leftKH != rightKH)
	{
		puts("括号不匹配!\n");
		return EOF;
	}
	
	ps = s;
	while(*ps)	//解析字符串并入栈
	{
		if(isNum(*ps) || *(ps) == '-' && (isOperator(*(ps-1)) == 1 || isOperator(*(ps-1)) == 2 || !*(ps-1)))	//如果是数字或者负数 
		{
			doNum();
			ps--;
		}
		else if(isOperator(*ps))	//如果是运算符 
		{
			if(GetTop_SeqStack(op, &o))	//如果运算符栈非空,读栈顶元素并进行操作 
			{
				if(*ps == '(') Push_SeqStack(op, operatorToDouble(*ps));
				else if(*ps == ')')	//如果遇到')',将()里的元算符取出进行计算
				{
					while((int)o != 5)
					{
						doOperator();
						GetTop_SeqStack(op, &o);
					}
					Pop_SeqStack(op, &o);
				}
				else if(priority(operatorToDouble(*ps)) > priority(o))			//如果当前运算符优先级大于栈顶运算符优先级
				{
					Push_SeqStack(op, operatorToDouble(*ps));	//直接入栈
				}
				else
				{
					while(!Empty_SeqStack(op) && priority(operatorToDouble(*ps)) <= priority(o))	//如果栈顶运算符的优先级大于当前运算符,将栈顶元素进行计算
					{
						doOperator();																//直到符合条件
						GetTop_SeqStack(op, &o);
					}
					Push_SeqStack(op, operatorToDouble(*ps));
				}
			}
			else Push_SeqStack(op, operatorToDouble(*ps));
		}
		else
		{
			printf("表达式错误!\n");
			return EOF;
		}
		ps++;
	}

	while(!Empty_SeqStack(op))
		doOperator();
	
	GetTop_SeqStack(num, &x);
	printf("结果为:%lf\n", x);
	
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43302818/article/details/85254520