栈的应用之表达式求值(二)

栈的应用之表达式求值

前面我们实现了栈的顺序结构以及链式结构,现在我准备试一试用栈来实现表达式的求值。

使用栈的顺序结构作为基础,利用栈结构FILO的特点进行表达式的求值。

表达式包括起始符、结束符、数字、运算符、界限符这几个基本的元素,起始符和结束符可以自定义,但是不要数字、运算符、界限符重复,这里我是用了'#'来作为起始符和结束符。数字在我这里只实现了0-9,运算符为加(+)、减(-)、乘(*)、整除(/),更复杂的功能以后再根据需要来实现。界限符指的是左括号‘(’和右括号‘)’。

在这里我们需要了解一些关于ascii码存储各个运算符号以及数字的小知识点。下面列了一个表来直观的表示:

数字及运算符十进制十六进制二进制
048300011 0000
149310011 0001
250320011 0010
351330011 0011
452340011 0100
553350011 0101
654360011 0110
755370011 0111
856380011 1000
957390011 1001
#35230010 0011
*422A0010 1010
+432B0010 1011
-452D0010 1101
/472F0010 1111
(40280010 1000
)41290010 1001

这里我们需要注意一下的是每个数字或运算符对应的二进制形式,这是他们在计算机中存储的形式,当我们通过键盘输入的所有信息,当时用了getchar这个函数后,都被处理成一个一个的字符,例如输入23,处理起来就是2(00110010),3(00110011),这显然不是我们想要的结果,所以需要对这样的输入数据进行处理,例如通过一个int型变量来存储,将每一个char型数据赋予一定的权值,最后赋值给4个字节的int型变量。不过这样就需要另外再写一个函数了,本文只写到了0-9数字之间的带括号的加减乘除运算,至于实现更多数字的计算器功能,等后面再写吧。

编译环境vc++6.0,下面是完整的代码:

#include <stdio.h>  
#include <stdlib.h>  
#include <ctype.h>

#define SElemType int  
#define STACK_INIT_SIZE 100  
#define STACK_INCRECEMENT 10  
#define STATUS int  
#define ERROR 0  
#define OK 1  
#define null 0  
#define TRUE 1  
#define FALSE 0  
  
typedef struct{  
    SElemType *top;  
    SElemType *base;  
    int stacksize;  
}Stack;  
  
STATUS Stack_Init(Stack *s)  
{  
    s->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));  
    if(s->base == null)return ERROR;  
    s->top = s->base;  
    s->stacksize = STACK_INIT_SIZE;  
    return OK;  
}  
//若栈为空,返回TRUE,否则为FALSE  
STATUS StackEmpty(Stack *s)  
{  
    if(s->top == s->base)return TRUE;  
    else return FALSE;  
    return OK;  
}  
  
STATUS Pop(Stack *s,SElemType *e)  
{  
    if(s->top == s->base)return ERROR;  
    *e = *--s->top;//栈顶指针一定要先自减,因为它始终在push入栈的最后一个数据之上  
    return OK;  
}  
  
STATUS Push(Stack *s,SElemType e)  
{  
    if(s->top - s->base >=STACK_INIT_SIZE)  
    {  
        s->base = (SElemType *)realloc(s->base,(s->stacksize+STACK_INCRECEMENT)*sizeof(SElemType));  
        if(s->base == null)return ERROR;  
        s->top = s->base + s->stacksize;  
        s->stacksize += STACK_INCRECEMENT;  
    }  
    *s->top++ = e;  
    return OK;  
}  

int Gettop(Stack *s)
{
	return 	*(s->top-1);
}
//比较两个运算符的优先级
char Precede(char a,char b)
{
	if(a == '#')
	{
		if(b == '#')return '=';
			else return '<';
	}
	if(a == ')')return '>';
	if(a == '(')
	{
		if(b == ')')return '=';
		else return '<';
	}
	if(a == '/')
	{
		if(b == '(')return '<';
			else return '>';
	}
	if(a == '*')
	{
		if(b == '(')return '<';
		else return '>';
	}
	if(a == '-')
	{
		if(b == '*'||b == '/'||b == '(')
			return '<';
		else return '>';
	}
	if(a == '+')
	{
		if(b == '*'||b == '/'||b == '(')return '<';
		else return '>';
	}
}
int Operate(int a, char theta,int b)
{
	a &=0x0f;b &=0x0f;
	switch(theta)
	{
	case '+':
		return (a + b);break;
	case '-':
		return (a - b);break;
	case '*':
		return (a * b);break;
	case '/':
		return (a / b);break;
	}
}

int main()
{
	char theta;
	int a,b,c;
	Stack OPTR,OPND;
	Stack_Init(&OPTR);
	Push(&OPTR,'#');
	Stack_Init(&OPND);
	c=getchar();
	while(c != '#' || Gettop(&OPTR) != '#')
	{
		if(isdigit(c))
		{
			Push(&OPND,c);
			c=getchar();
		}
		else 
			switch(Precede((char)Gettop(&OPTR),(char)c))
		{
			case '<':
				Push(&OPTR,c);c = getchar();
				break;
			case '=':
				Pop(&OPTR,&c);c = getchar();
				break;
			case '>':
				Pop(&OPTR,&theta);
				Pop(&OPND,&b);
				Pop(&OPND,&a);
				Push(&OPND,Operate((int)a,(char)theta,(int)b));
				break;

		}
	}
	printf("%d\n",Gettop(&OPND));
}


当输入为:1+2*(3-1)#

输出结果为:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值