栈实例(转载)

栈:只允许在一端进行插入和删除操作,(后进先出)

实现简单的四则运算 包括 +-*/以及()

参考博客: http://blog.csdn.net/zhaishaojiang/article/details/40017791

工程一共包含5个文件(由于代码不多,未分成头文件和实现)
1. OptrStack.h OptrStack.c 操作符栈 包含基本的栈结构定义和操作方法
2. OpndStack.h OpndStack.c 操作数栈 包含基本的栈结构定义和操作方法
3. main.c : 测试文件 包含运算的方法

    定义两个栈分别用于存储操作符和操作数;

    栈所具有的功能有:置栈空,判栈空,入栈,出栈,取栈顶;

    将输入的算术表达式存入字符数组中;

    将表达式中的运算符划分优先级;

    进行双目运算,即+,-,*,/;

    将表达式压入栈中,并计算表达式结果。(思路:将操作符压入操作符栈中,将操作数压入操作数栈中。过程:判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,再将当前的操作符压入操作符栈中。)
OpndStack.h
    #include <stdio.h>
    #include <stdlib.h>
    #define MAXSIZE2 100

    typedef struct
    {
        double date[MAXSIZE2];
        int top;
    }OpndStack;     //操作数结构体

    /*-------操作数相关操作-------*/
    OpndStack *Init_OpndStack();/*置栈空*/
    int Empty_OpndStack(OpndStack *t);/*判空栈*/
    int Push_OpndStack(OpndStack *t, double y);/*入栈(注意:判断栈是否已满)*/
    double Pop_OpndStack(OpndStack *t);/*出栈(注意:判断栈是否已空)*/
    double GetTop_OpndStack(OpndStack *t);/*取栈顶元素*/
OpndStack.c
    #include "OpndStack.h"

    /*-------操作数相关操作-------*/

    OpndStack *Init_OpndStack()/*置栈空*/
    {
        OpndStack *t;

        t = (OpndStack *)malloc(sizeof(OpndStack));
        t->top = -1;
        return t;
    }

    int Empty_OpndStack(OpndStack *t)/*判空栈*/
    {
        if(t->top == -1)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }

    int Push_OpndStack(OpndStack *t, double y)/*入栈(注意:判断栈是否已满)*/
    {
        if(t->top == MAXSIZE2 - 1)
        {
            return 0;
        }
        else
        {
            t->top ++;
            t->date[t->top] = y;
            return 1;
        }
    }

    double Pop_OpndStack(OpndStack *t)/*出栈(注意:判断栈是否已空)*/
    {
        double y;       //接收要出栈的元素

        if( Empty_OpndStack(t) )
        {
            return 0;
        }
        y = t->date[t->top];
        t->top --;
        return y;
    }

    double GetTop_OpndStack(OpndStack *t)/*取栈顶元素*/
    {
        if( Empty_OpndStack(t) )
        {
            return 0;
        }
        else
        {
            return (t->date[t->top]);
        }
    }
OptrStack.h
    #include <stdio.h>
    #include <stdlib.h>
    #define MAXSIZE1 100

    typedef struct
    {
        char date[MAXSIZE1];
        int top;
    }OptrStack;     //操作符结构体

    /*-------操作符相关操作-------*/
    OptrStack *Init_OptrStack();    /*置栈空*/
    int Empty_OptrStack(OptrStack *s);/*判空栈*/
    int Push_OptrStack(OptrStack *s, char x);/*入栈(注意:判断栈是否已满)*/
    char Pop_OptrStack(OptrStack *s);/*出栈(注意:判断栈是否已空)*/
    char GetTop_OptrStack(OptrStack *s);/*取栈顶元素,先判空*/
OptrStack.c
    #include "OptrStack.h"

    /*-------操作符相关操作-------*/

    OptrStack *Init_OptrStack() /*置栈空*/
    {
        OptrStack *s;

        s = (OptrStack *)malloc(sizeof(OptrStack));
        s->top = -1;
        return s;
    }

    int Empty_OptrStack(OptrStack *s)/*判空栈*/
    {
        if(s->top == -1)
        {
            return 1;       //如果栈为空,则返回真数
        }
        else
        {
            return 0;       //反之,返回零
        }
    }

    int Push_OptrStack(OptrStack *s, char x)/*入栈(注意:判断栈是否已满)*/
    {
        if(s->top == MAXSIZE1 - 1)
        {
            return 0;
        }
        else
        {
            s->top ++;      //栈顶指针向上移,再赋值
            s->date[s->top] = x;
            return 1;
        }
    }

    char Pop_OptrStack(OptrStack *s)/*出栈(注意:判断栈是否已空)*/
    {
        int x;      //接收要出栈的元素

        if( Empty_OptrStack(s) )
        {
            return 0;
        }
        x = s->date[s->top];
        s->top --;
        return x;
    }

    char GetTop_OptrStack(OptrStack *s)/*取栈顶元素,先判空*/
    {
        if( Empty_OptrStack(s) )
        {
            return 0;
        }
        else
        {
            return (s->date[s->top]);
        }
    }
main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "OpndStack.h"
    #include "OptrStack.h"

    int Rank(char op);          //划分运算符的优先级
    double Operate(double a, double b, char op);    //运算操作
    void Handle_str(char str[]);        //将储存表达式的字符数组压入栈内,并运算

    int main()
    {
        char str[100];

        printf("请输入算术表达式(功能:+,-,*,/。可带括号!):\n");
        scanf("%s", str);

        Handle_str(str);

        return 0;
    }

    int Rank(char op)           //划分运算符的优先级
    {
        int x;

        switch(op)
        {
        case '#':
            x = 0;break;
        case '(':
            x = 1;break;
        case '+':
        case '-':
            x = 2;break;
        case '*':
        case '/':
            x = 3;break;
        }

        return x;
    }

    double Operate(double a, double b, char op) //运算操作
    {
        double c;

        switch(op)
        {
        case '+':
            c = a + b;break;
        case '-':
            c = a - b;break;
        case '*':
            c = a * b;break;
        case '/':
            if(b == 0)
            {
                printf("分母为零!\n");
                return 0;
            }
            else
                c = a / b;break;
        default:
            printf("输入的字符非法!\n");
            break;
        }
        return c;
    }

    void Handle_str(char str[])     //将储存表达式的字符数组压入栈内
    {
        OptrStack *optr = Init_OptrStack(); //初始化操作符栈
        OpndStack *opnd = Init_OpndStack();     //初始化操作数栈
        int i,j;        //i,j为循环变量,a,b接收从操作数栈中出栈的元素
        double f,a,b;       //接收将字符数转换为浮点数的值
        char d[100];    //储存字符串中连续的‘数’
        char op;        //接收从操作符栈中出栈的元素

        Push_OptrStack(optr, '#');  //先往操作符栈中压入'#'
        for (i = 0; str[i]; i++)
        {
            switch(str[i]){
            case '+':
            case '-':
                /*先判断当前运算符与操作符栈栈顶元素的优先级,如果高于栈顶元素,则入栈;
                    小于栈顶元素,则从操作数栈中依次出两个数,并将操作符栈中栈顶元素出栈,
                    再将从操作数栈中出的两个数,按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,
                    再将当前的操作符压入操作符栈中。*/
                if(GetTop_OptrStack(optr) == '#' || GetTop_OptrStack(optr) == '(')
                {
                    Push_OptrStack(optr, str[i]);//入栈
                }
                else
                {
                    a = Pop_OpndStack(opnd);//接收从操作数栈中出栈的元素
                    b = Pop_OpndStack(opnd);//接收从操作数栈中出栈的元素
                    op = Pop_OptrStack(optr);//接收从操作符栈中出栈的元素
                    Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中
                    Push_OptrStack(optr, str[i]);
                }
                break;
            case '*':
            case '/':
                if(Rank(str[i]) > Rank(GetTop_OptrStack(optr)) || GetTop_OptrStack(optr) == '(')
                {
                    Push_OptrStack(optr, str[i]);
                }
                else
                {
                    a = Pop_OpndStack(opnd);
                    b = Pop_OpndStack(opnd);
                    op = Pop_OptrStack(optr);
                    Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中
                    Push_OptrStack(optr, str[i]);
                }
                break;
            case '(':
                Push_OptrStack(optr, str[i]);
                break;
            case ')':
                while(GetTop_OptrStack(optr) != '(')
                {
                    a = Pop_OpndStack(opnd);
                    b = Pop_OpndStack(opnd);
                    op = Pop_OptrStack(optr);
                    Push_OpndStack(opnd, Operate(b, a, op)); //将计算后的值压入操作数栈中
                }
                Pop_OptrStack(optr);
                break;
            default:
                j=0;
                do{
                    d[j++]=str[i];
                    i++;
                }while(str[i]>='0' && str[i]<='9'|| str[i]=='.');  //可存入一个或多个数字字符
                d[j]='\0';     //将输入的连续多个数字字符拼成了字符串
                i--;
                f=atof(d);  //调用库函数atof()将字符数转换为浮点数
                Push_OpndStack(opnd, f);    //将转换后的数压入操作数栈中
                break;
            }

        }
        while(GetTop_OptrStack(optr) != '#')
        {
            a = Pop_OpndStack(opnd);
            b = Pop_OpndStack(opnd);
            op = Pop_OptrStack(optr);
            Push_OpndStack(opnd, Operate(b, a, op));//将计算后的值压入操作数栈中
        }
        printf("表达式%s = %g\n", str, GetTop_OpndStack(opnd));//将操作数栈中的元素(即表达式的最终结果)打印出来
    }

个人博客 欢迎来访: http://ay2626.me

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值