数据结构之栈的应用--四则运算表达式求值

称9+(3-1)*5+10/2这样的表达式为中缀表达式,称9 3 1 - 3 * + 10 2 / +这样的形式为后缀(逆波兰    RPN)表达式(数字在前运算符在后)。

一、将中缀表达式转为后缀表达式:

1、遍历中缀表达式中的数字和符号

      ①对于数字:直接输出(即直接成为后缀表达式的一部分);

      ②对于符号:

            1`左括号:进栈;

            2`符号:与栈顶符号进行优先级比较

                   · 栈顶符号优先级低则进栈;

                   · 栈顶符号优先级不低则将栈顶符号弹出并输出之后 再将此符号压入栈中;

            3`右括号:将栈顶符号弹出并输出,知道匹配左括号(左括号也弹出);

    2、遍历结束:

            将栈中的所有符号弹出并输出。      

算法框架:

transform(exp)
{
	创建栈S;
	i=0;
	while(exp[i] != '\0')
	{
		if(exp[i]为数字)
		{
			output(exp[i]);
		}
		else if(exp[i]为符号)
		{
			while(exp[i]优先级 <= 栈顶符号的优先级)
			{
				output(栈顶符号);
				pop(S);
			}
			push(S,exp[i]);
		}
		else if(exp[i]为左括号)
		{
			push(S,exp[i]);
		}
		else if(exp[i]为右括号)
		{
			while(栈顶符号不为左括号)
			{
				output(栈顶符号);
				pop(S);
			}
			从S中弹出左括号;
		}
		else
		{
			报错,停止循环;
		}
		i++;
	}
	
	while( (size(S) > 0) && (exp[i]  == '\0') )
	{
		output(栈顶符号);
		pop(S);
	}
}


二、四则运算

    1、遍历后缀表达式中的数字和符号

        ①对于数字:进栈;

        ②对于符号:

                ·从栈中弹出右操作数;

                ·从栈中弹出左操作数;

                ·根据符号进行运算;

                ·将结果压入栈中;

    2、遍历结束:

            栈中的唯一数字为计算结果。

算法框架:

compute(exp)
{
	创建栈S;
	i=0;
	while(exp[i] != '\0')
	{
		if(exp[i]为数字)
		{
			push(S, exp[i]);
		}
		elseif(exp[i]为符号)
		{
            1从栈中弹出右操作数;
			2从栈中弹出左操作数;
			3根据符号进行运算;
			4push(S, 结果);			
		}
		else
		{
			报错,停止循环;
		}
		i++;
	}
	if( (size(S) == 1) && (exp[i] == '\0') )
	{
		栈中唯一的数字为运算结果;
	}
	
	返回结果;
}


三、代码实现

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "Compute.h"
#include "LinkStack.h"

int Isnumber(char c)
{
	return ('0' <= c ) && ( '9' >= c );
}

int Isoperator(char c)
{
	return ( '+' == c ) || ( '-' == c ) || ( '*' == c ) || ( '/' == c );
}

int Priority(char c)
{
	int ret = 0;
	if( ('+' == c) || ('-' == c) )
		ret = 1;
	if( ('*'== c) || ('/'==c) )
		ret =2;
	return ret;
}

int Isleftbracket(char c)
{
	return ( '(' == c );
}

int Isrightbracket(char c)
{
	return ( ')' == c );
}

char* Transform(const char* exp)
{
	LinkStack* stack = LinkStack_Create();
	int i = 0;
	char* ret = (char*)malloc(sizeof(char));  //动态申请字符串数组
	int a = 0;   //用于动态改变字符串数组大小
	while( exp[i] != '\0' )
	{
		if( Isnumber(exp[i]) )
		{
			ret = (char*)realloc(ret,(a+1)*sizeof(char));   //可更改由malloc函数分配的内存空间大小
			if( ret == NULL )
			{
				printf("error");
				break;
			}
			ret[a] = exp[i];
			a++;
		}
		else if( Isoperator(exp[i]) )
		{
			while( Priority(exp[i]) <= Priority((char)(long)LinkStack_Top(stack)) )
			{
				ret = (char*)realloc(ret,(a+1)*sizeof(char));
				if( ret == NULL )
				{
					printf("error");
					break;
				}
				ret[a] = (char)(long)LinkStack_Top(stack);
				a++;
				LinkStack_Pop(stack);
			}
			LinkStack_Push( stack, (void*)(long)exp[i] );
		}
		else if( Isleftbracket(exp[i]) )
			LinkStack_Push( stack, (void*)(long)exp[i] );
		else if( Isrightbracket(exp[i]) )
		{
			while( !Isleftbracket((char)(long)LinkStack_Top(stack)) )
			{
				ret = (char*)realloc(ret,(a+1)*sizeof(char));
				if( ret == NULL )
				{
					printf("error");
					break;
				}
				ret[a] = (char)(long)LinkStack_Top(stack);
				a++;
				LinkStack_Pop(stack);
			}
			LinkStack_Pop(stack);
		}
		else 
		{
			printf("Invalid expression!!!");
			break;
		}
		i++;
	}
	while( (LinkStack_Size(stack) > 0) && ( exp[i] == '\0' ) )
		{
			ret = (char*)realloc(ret,(a+1)*sizeof(char));
			if( ret == NULL )
			{
				printf("error");
				break;
			}
			ret[a] = (char)(long)LinkStack_Top(stack);
			a++;
			LinkStack_Pop(stack);
		}
	LinkStack_Destroy(stack);
	return ret;
}

long value(char c)
{
	return (c-'0');
}

long express(long left, long right, char exp)
{
	long ret = 0;
	switch(exp)
	{
		case '+' :
			ret = left + right;
			break;
		case '-' :
			ret = left - right;
			break;
		case '*' :
			ret = left * right;
			break;
		case '/' :
			ret = left /right;
			break;
	}
	return ret;
}

long Compute(const char* exp)
{
	LinkStack* stack = LinkStack_Create();
	long ret = 0;
	int i = 0;
	while(exp[i] != '\0')
	{
		if( Isnumber(exp[i]) )
			LinkStack_Push( stack, (void*)value(exp[i]) );
		else if( Isoperator(exp[i]) )
		{
			long right = (long)LinkStack_Pop(stack);
			long left = (long)LinkStack_Pop(stack);
			long result = express(left, right, exp[i]);

			LinkStack_Push(stack, (void*)result);
		}
		else
		{
			printf("Invalid expression!!!");
			break;
		}
		i++;
	}
	if( (LinkStack_Size(stack) == 1) && (exp[i] == '\0') )
		ret = (long)LinkStack_Pop(stack);
	else
		printf("Invalid expression");
	LinkStack_Destroy(stack);
	return ret;
}

猜你喜欢

转载自blog.csdn.net/qq_31820761/article/details/80764785