栈应用---计算表达式

为实现运算符优先级,可以使用两个工作栈,一个用来存操作数(opnd),另一个存操作符(optr)

基本思想是:1.首先置两个栈为空栈.依次读入表达式中的每个字符,若是操作数,则进opnd,若是运算符,则和optr栈顶元素比较,这时分三种情况

1.栈顶元素优先级低

 直接进栈

2.相等('栈顶为'(',与之想比较的操作符为')'')

出栈,(脱去左括号)

3.栈顶元素优先级大

        1.optr出栈op,得到操作符

        2opnd,出栈,s1,出栈s2,

        3.s1,s2,op,进行运算,并将结果放入opnd中

 

 

上述操作完成后,基本工作已经完成,之后,再一一取栈中元素,运算

               +        -          *          /            (         )           #

+             >        >         <         <           <        >          >          

-              >        >          <        <           <        >           > 

*             >          >         >         >          <        >          >   

/              >           >        >        >           <         >          >

(             <         <           <        <           <          =            

)            >         >             >        >                      >         >

#            <         <           <         <          <                       =

#include <stdio.h>
#include <malloc.h>
#include <string.h>


#define NULL 0
#define TRUE 1
#define FALSE 0

#define RIGHT 1
#define DOWN  2
#define LEFT  3
#define UP    4

const int width = 10;
const int height = 10;
int maze[height][width]={
	//0,1,2,3,4,5,6,7,8,9
	{1,1,1,1,1,1,1,1,1,1},//0
	{1,0,0,1,0,0,0,1,0,1},//1
	{1,0,0,1,0,0,0,1,0,1},//2
	{1,0,0,0,0,1,1,0,0,1},//3
	{1,0,1,1,1,0,0,0,0,1},//4
	{1,0,0,0,1,0,0,0,0,1},//5
	{1,0,1,0,0,0,1,0,0,1},//6
	{1,0,1,1,1,0,1,1,0,1},//7
	{1,1,0,0,0,0,0,0,0,1},//8
	{1,1,1,1,1,1,1,1,1,1},//9
};

int foot[height][width]={0};

typedef struct PosType
{
	int x;
	int y;
}PosType;

/*typedef struct {
	PosType pos;
	int di;
}ElemType;
*/

typedef char ElemType;

typedef struct
{
	int **path;
	int width;
	int height;
}MazePath;
//地图
MazePath mazepath = {(int **)maze,width,height}; 


typedef struct _stack
{
	ElemType data;
	struct _stack* next;
}Stack , *PStack;

const int nLEN = sizeof(Stack);

void InitStack(PStack* head)
{
	(*head) = (PStack)malloc(nLEN);
//	(*head)->data = NULL;
	(*head)->next = 0;
}

void DestroyStack(PStack *head)
{
	PStack p = *head;
	PStack p1 = p;
	while(p)
	{
		p = p->next;
		free(p1);
		p1 = p;
	}
}

void CleadStack(PStack *head)
{

	PStack p = (*head)->next;
	PStack p1 = p;
	while(p)
	{
		p = p->next;
		free(p1);
		p1 = p;
	}
}

int StackEmpty(PStack s)
{
	s = s->next;
	if(s!=NULL)
		return FALSE;
	else return TRUE;
}

int StackLength(PStack s)
{
	s = s->next;
	int nSize = 0;
	while(s!=NULL)
	{
		nSize++;
		s = s->next;
	}
	return nSize;
}

int GetTop(PStack s,ElemType *data)
{
	if(!StackEmpty(s))
	{
		s = s->next;
		*data = s->data;
		return TRUE;
	}
	return FALSE;
}

int Push(PStack s,ElemType data)
{
	PStack temp = (PStack)malloc(nLEN);
	temp->data = data;
	temp->next = NULL;

	//
	temp->next = s->next;
	s->next = temp;

	return TRUE;
}

int Pop(PStack s,ElemType *data)
{
	if(StackEmpty(s))
		return FALSE;

	PStack temp = s->next;
	*data = temp->data;
	s->next = s->next->next;

	free(temp);

	return TRUE;
}

//能否通过
int Canpass(PosType pos)
{
	int x = pos.x;
	int y = pos.y;
	//已经走过
	if(foot[y][x]==1)
	{
		return FALSE;
	}
	//有障碍
	int (*p)[width] = (int(*)[width])(mazepath.path);
	if(p[y][x]==1)
	{
		return FALSE;
	}
	return 1;
}

//留下足迹
void MarkFoot(PosType pos)
{
	int x = pos.x;
	int y = pos.y;
	foot[y][x] = 1;
}

PosType NextPos(PosType pos,int di)
{
	PosType p;
	if(di==RIGHT)
	{
		p.x = pos.x +1;
		p.y = pos.y;
	}
	else if(di == LEFT)
	{
		p.x = pos.x-1;
		p.y = pos.y;
	}
	else if(di==DOWN)
	{
		p.x = pos.x;
		p.y = pos.y+1;
	}
	else if(di == UP)
	{
		p.x = pos.x;
		p.y = pos.y-1;
	}

	return p;
}
char Precede(char ch1,char ch2)
{
//	if(ch1 == ch2)
//		return '=';
	if(ch1==' ')
		return '<';

	if(ch1=='+')
	{
		if(ch2=='+')
			return '<';

		if(ch2=='-')
			return '>';

		if(ch2=='*')
			return '<';

		if(ch2=='/')
			return '<';

		if(ch2=='(')
			return '<';

		if(ch2==')')
			return '>';
	}

	else if(ch1=='-')
	{
		if(ch2=='+')
			return '<';
		
		if(ch2=='-')
			return '>';
		
		if(ch2=='*')
			return '<';
		
		if(ch2=='/')
			return '<';
		
		if(ch2=='(')
			return '<';
		
		if(ch2==')')
			return '>';

	}

	else if(ch1=='*')
	{
		if(ch2=='+')
			return '>';
		
		if(ch2=='-')
			return '>';
		
		if(ch2=='*')
			return '>';
		
		if(ch2=='/')
			return '>';
		
		if(ch2=='(')
			return '<';
		
		if(ch2==')')
			return '>';
	}

	else if(ch1=='/')
	{
		if(ch2=='+')
			return '>';
		
		if(ch2=='-')
			return '>';
		
		if(ch2=='*')
			return '>';
		
		if(ch2=='/')
			return '>';
		
		if(ch2=='(')
			return '<';
		
		if(ch2==')')
			return '>';
	}

	else if(ch1=='(')
	{
		if(ch2=='+')
			return '<';
		
		if(ch2=='-')
			return '<';
		
		if(ch2=='*')
			return '<';
		
		if(ch2=='/')
			return '<';
		
		if(ch2=='(')
			return '<';
		
		if(ch2==')')
			return '=';
	}

	else if(ch1==')')
	{
		if(ch2=='+')
			return '>';
		
		if(ch2=='-')
			return '>';
		
		if(ch2=='*')
			return '>';
		
		if(ch2=='/')
			return '>';
		
		if(ch2=='(')
			return ' ';
		
		if(ch2==')')
			return '>';
	}
}

int IsNum(char ch)
{
	if(ch<='9' && ch>='0')
		return TRUE;
	return FALSE;
}

char calc(char a,char op,char b)
{
	
	if(op=='+')
		return a+b;
	if(op=='-')
		return a-b;
	if(op=='*')
		return a*b;
	if(op=='/')
		return a/b;
}

int EvalueateExpression(char *buf,int nlen)
{
	char ch=0;
	int i=0;
	PStack opnd,optr;
	InitStack(&opnd);//操作数
	InitStack(&optr);//操作符
	ElemType nd;
	ElemType tr;
	for(i = 0 ; i < nlen ; i++)
	{
		ch = buf[i];
		//数字
		if(IsNum(ch))
		{
			nd = ch-48;
			Push(opnd,nd);
		}
		//操作符
		else
		{
			tr = ' ';
			GetTop(optr , &tr);
			char cRet = Precede(tr , ch);

			if(cRet =='<')
			{
				Push(optr,ch);
			}

			else if(cRet =='=')
			{
				Pop(optr,&tr);
			}

			else if(cRet=='>')
			{
				char op;
				Pop(optr,&op);
				char a1,a2;
				Pop(opnd,&a1);
				Pop(opnd,&a2);
				char ret = calc(a2 , op , a1);
				Push(opnd , ret);
				i--;
			}
		}
	}
	while(!StackEmpty(optr))
	{
		char op;
		Pop(optr,&op);
		char a1,a2;
		Pop(opnd,&a1);
		Pop(opnd,&a2);
		char ret = calc(a2 , op , a1);
//		printf("ret = %d",ret);
		Push(opnd , ret);
	}
	if(!StackEmpty(opnd))
	{
		char cRet = 0;
		Pop(opnd,&cRet);
		printf("%-d\n",cRet);
	}
	return 0;

	
}


int main()
{
	char buf[]="3*5";
	int nlen = strlen(buf);
	EvalueateExpression(buf , nlen);
	printf("\n");
	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值