hdu 1237 简单计算器 栈

这个题目是大部分人都是用栈来写的,本周训练老师也讲了两次栈的原理。自己最近也看了数据结构中与栈有关的内容,还是比较深刻理解了没有括号情况下表达式求解。

#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;

char s[250],post[250];//s是输入的中缀表达式,post是转化出来的后缀表达式
stack<char>op;//存放运算符
stack<double>num;//存放运算过程中的数字

int isnum(char c)//判断字符是否为数字
{
    if(c>='0'&&c<='9')
        return 1;
    return 0;
}

double opmode(char c)//运算符优先级判定
{
    if(c=='+') return 1;
    if(c=='-') return 2;
    if(c=='*') return 3;
    if(c=='/') return 4;
    return -1;
}

void change()//将中缀表达式转化为后缀表达式
{
    int i,j=0,len;
    memset(post,0,sizeof(post));
    len=strlen(s);
    for(i=0; i<len; i++)
    {
        if(s[i]==' ') continue;
        post[j++]=' ';//空格是关键,主要是区分数字用的,出现俩个连续的1会当成11,而不是两个1
        while(isnum(s[i])) post[j++]=s[i++];
        int c=opmode(s[i]);
        //当前运算的与栈顶运算符号进行比较
        if(c!=-1)
        {
            if(c<=2)//优先级小于等于栈顶的运算符时,将栈顶的运算符输入到数组中
            {
                while(!op.empty())//因为+-遇到任何一个栈内符号都会小于或等于,所以将所有运算符输出
                {
                    post[j++]=op.top();
                    op.pop();
                }
            }
            else
            {
                while(!op.empty()&&opmode(op.top())>2)//栈顶运算符是*/时,才将栈顶的输出
                {
                    post[j++]=op.top();
                    op.pop();
                }
            }
            op.push(s[i]);//优先级大时或者上面操作后将当前运算符入栈
        }
    }
    while(!op.empty())//对象处理完毕将栈中存留的运算符一并输出
    {
        post[j++]=op.top();
        op.pop();
    }
}

double cal()//计算后缀表达式
{
    while(!num.empty()) num.pop();//清空栈
    int i=0,len;
    len=strlen(post);
    for(i=0;i<len;i++)
    {
        if(post[i]==' ') continue;
        double cur=0;
        bool hasnum=0;
        while(isnum(post[i]))//提取数字
        {
            cur*=10;
            cur+=post[i]-'0';
            hasnum=1;
            i++;
        }
        if(hasnum) num.push(cur);
        if(opmode(post[i])!=-1)//遇到运算符,提取栈顶两个数字进行计算
        {
            double n1=num.top();
            num.pop();
            double n2=num.top();
            num.pop();
            switch(post[i])
            {
                case '+':num.push(n1+n2);break;
                case '-':num.push(n2-n1);break;
                case '*':num.push(n1*n2);break;
                case '/':num.push(n2/n1);break;
            }
        }
    }
    return num.top();//输出答案
}

int main()
{
    while(gets(s))
    {
        if(strcmp(s,"0")==0) break;
        change();
        printf("%.2f\n",cal());
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/

posted @ 2015-03-15 20:47  xryz  阅读(172)  评论(0编辑  收藏  举报