栈的应用实例--简单表达式的计算

#include
#include
#include "LinkStack.h"


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


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


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


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


int priority(char c)//优先级判断函数
{
    int ret = 0;
    
    if( (c == '+') || (c == '-') )
    {
        ret = 1;
    }
    
    if( (c == '*') || (c == '/') )
    {
        ret = 2;
    }
    
    return ret;
}


void output(char c)
{
    if( c != '\0' )
    {
        printf("%c", c);//打印字符
    }
}


void transform(const char* exp)//中缀表达式转后缀表达式
{
    LinkStack* stack = LinkStack_Create();//创建一个栈
    int i = 0;
    
    while( exp[i] != '\0' )//依次遍历
    {
        if( isNumber(exp[i]) )//判断是否为数字
        {
            output(exp[i]);//直接输出数字
        }
        else if( isOperator(exp[i]) )//是否为符号
        {
            while( priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack)) )//符号优先级比栈顶低
            {
                output((char)(int)LinkStack_Pop(stack));
            }
            
            LinkStack_Push(stack, (void*)(int)exp[i]);//符号优先级比栈顶高,进栈
        } 
        else if( isLeft(exp[i]) )//如果是左括号
        {
            LinkStack_Push(stack, (void*)(int)exp[i]);
        } 
        else if( isRight(exp[i]) )//如果是右括号
        {
            char c = '\0';
            
            while( !isLeft((char)(int)LinkStack_Top(stack)) )//判断栈顶是否是左括号
   {
                output((char)(int)LinkStack_Pop(stack));
            }
            
            LinkStack_Pop(stack);
        }
        else
        {
            printf("Invalid expression!");
            break;
        }
        
        i++;
    }
    
    while( (LinkStack_Size(stack) > 0) && (exp[i] == '\0') )//输出所有元素
    {
        output((char)(int)LinkStack_Pop(stack));
    }
    
    LinkStack_Destroy(stack);//销毁栈
}


int value(char c)//将字符值转换为数字值
{
    return (c - '0');
}


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


int compute(const char* exp)
{
    LinkStack* stack = LinkStack_Create();
    int 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]) )
        {
            int right = (int)LinkStack_Pop(stack);//跳出右操作数
            int left = (int)LinkStack_Pop(stack);//跳出左操作数
            int 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 = (int)LinkStack_Pop(stack);
    } 
    else 
    {
        printf("Invalid expression!");//当栈中最后有两个数字时,说明缺少一个运算符
    }
    
    LinkStack_Destroy(stack);
    
    return ret;
}


int main()
{
transform("9+(3-1)*5+8/2");
printf("\n");
    printf("9 + (3 - 1) * 5 + 8 / 2 = %d\n",compute("931-5*+82/+"));//此处有问题,不可参考!
    return 0;
}

你可能感兴趣的:(数据结构)