第六次课程作业

本文介绍了一个使用栈实现四则运算表达式解析与计算的算法。该算法能够处理包含括号的中缀表达式,将其转换为后缀表达式并计算结果。文章详细展示了如何利用栈的数据结构来验证表达式的合法性和计算表达式的值。

Github

题目描述

  • 本次作业要求将四则运算的核心部分采取栈的知识进行解决。即表达式生成的合法性检验、表达式结果计算。
  • 学习C++界面编程,可以学QT、MFC或者VS,选择其一即可,用博客记录学习到的知识以及心得体会。

    作业要求

  • 本次作业要求实现核心算法,请将表达式生成的代码及相关的检验、计算表达式结果的代码贴在博客中,并对代码进行必要的解释。
  • 发表一篇博客,博客内容为:提供本次作业的github链接,本次程序运行的截图,对界面编程的探索。

    核心算法

    之前认为改用栈实现计算之后,上次的框架需要做大改甚至重写,但没想到还是能用上的,而且需要改动的地方也不算是太多,节省了挺多时间。

    计算表达式结果的代码

    这一部分的思路来自这篇博客的介绍,具体实现本来是想采用c++栈方面的操作,但是写出来的那一版本的代码得不到想要的结果,还在检查bug中,所以模仿了这篇博客,用数组来实现栈的有关操作,这篇博客里的算法可用于实现十位及十位以上数的运算,因为我的程序是实现0~9以内数字的运算,所以我的代码省去了一些步骤。用栈实现计算,之前繁琐的计算过程被压缩成了一点,而且也更有逻辑和拓展性了。在对表达式的生成这一问题有进展之后,计算这一部分可以进一步拓展。
float Calculate::calculateresult(char s[30])
{
    int flag=0;
    string exp;                 //做栈使用
    char postexp[30];           //后缀表达式
    float st[30];                   //数值栈
    char ch;
    int i=0,j=0,top=-1;
    for(i=0;i<strlen(s);i++)            //将中缀表达式转化为后缀表达式
    {
        ch=s[i];
        if(ch=='(')                     //左括号
        {
            top++;
            exp[top]=ch;
            
        }
        else if(ch==')')                //若遇到右括弧“)”,则连续出栈输出,直到遇到左括弧“(”为止。其中,左括弧出栈但是并不输出 
        {
            while(exp[top]!='(')
            {
                postexp[j]=exp[top];
                top--;
                j++;
            }
            top--;
        }
        else if(ch=='+'||ch=='-')       //为'+'或'-'时,其优先级不大于栈顶任何运算符的优先级,直到')' 
        {
            while(top!=-1&&exp[top]!='(')
            {
                postexp[j]=exp[top];
                top--;
                j++;
            }
            top++;
            exp[top]=ch;
        }
        else if(ch=='*'||ch=='/')       //为'*'或'/'时,其优先级不大于栈顶为'*'或'/'的优先级,直到')'  
        {
            while(top!=-1&&exp[top]!='('&&(exp[top]=='*'||exp[top]=='/'))
            {
                postexp[j]=exp[top];
                j++;
                top--;
            }
            top++;
            exp[top]=ch;
        }
        else if(ch>='0'&&ch<='9')       //为数字,直接存入
        {
            postexp[j]=ch;
            j++;
        }
        else
        {
            continue;
        }
    }
    while(top!=-1)
    {
        postexp[j]=exp[top];
        j++;
        top--;
    }
    postexp[j]='\0';
    top=-1;
    for(i=0;i<strlen(postexp);i++)          //计算后缀表达式 
    {
        ch=postexp[i];
        if(ch=='+')                         //遇到操作符就弹出两个数 并将结果进栈   
        {
            st[top-1]=st[top-1]+st[top];
            top--;
        }
        if(ch=='-')
        {
            st[top-1]=st[top-1]-st[top];
            top--;
        }
        if(ch=='*')
        {
            st[top-1]=st[top-1]*st[top];
            top--;
        }
        if(ch=='/')
        {
            if(st[top]==0)          //防止出现除数为0的情况
            {
                flag=1;
                break;
            }
            else
            {
                st[top-1]=st[top-1]/st[top];
                top--;
            }
        }
        if(ch>='0'&&ch<='9')
        {
            top++;
            st[top]=ch-'0'; 
        }
    }
    if(flag==0)
        result=st[top];         //若未出现除数为0的情况,则栈顶元素即为式子结果
    else
        result=-1;
    return result;
}

相关的检验

在计算过程中有判断除数是否为0的部分。

bool Judge::Judgeresult(float res)          //判断式子是否符合要求,即结果为正整数 
{
    int test;
    test=res;
    if(test==res&&res>=0)
        return true;
    else
        return false;
}

表达式生成的代码

有点惭愧,不知道怎么用栈来比较好的处理括号,所以采用之前固定格式的方法来生成表达式了,就不把代码贴出来了。这个问题还在考虑中,因此这一部分放在最后。

运行截图

1092472-20170531223213696-1017846437.png

对界面编程的探索

选择了MFC,目前只是百度了一些有关内容,看得一头雾水,还要继续努力。

转载于:https://www.cnblogs.com/z031602148/p/6925795.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值