后缀表达式的应用(计算器)

闲着无聊打开了软基的课本  看见了后缀表达式 就没事写了个计算器玩玩 大神勿喷

我还是先说一下算法的原理吧

      

 

 

此计算机器只适用于正数之间的 加减乘除计算
       新增功能:
       1.新增加了小数的计算
       2.提升了计算的稳定性
       3.新增计算运行时间
       4.可输入大于9的操作数
       暂不支持有关的负数运算 
       版本号1.02
#include <iostream>
#include<windows.h>
#define  MAXSIZE 100
#define MAXSIZEOFDATA 10
#define IsSymbol   0
#define  IsData       1
using namespace std;

typedef  float typedata;
typedef struct
{
    char top;
    typedata data[MAXSIZE][2];
    //data[x][0]   记录的是数据
    //data[x][1]    记录的是数据类型  数据或者操作符
}stack;

char StackIsEmpty(stack  &st)
{
    if (st.top == -1)
        return 1;
    return 0;
}

void StackInit(stack &st)
{
    st.top = -1;
}

void StackPush(stack &st, typedata dat,char symbol )
{
    st.top++;
    st.data[st.top][0] = dat;
    st.data[st.top][1] = symbol;
}

typedata StackPop(stack &st)
{
    if (StackIsEmpty(st)==0)
    {
        --st.top;
        return st.data[st.top + 1][0];
    }
    return -1;
}

float  PowFloat(int y)
{
    if (y == 0)
        return 1;
    return  0.1*PowFloat(--y);
}

typedata StringToData(char *dat, int count)
{
    char i,j;
    typedata sum;
    sum = 0;
    if (count == 0)
        return 0;
    //遍历找到小数点的位置  位置记录为i
    for (i = 0; i < count; i++)
    {
        if (dat[i] == '.')
            break;
    }
    //没有小数点
    if (count == i)
    {
        for (i = 0; i < count;i++)
        {
            sum = sum * 10;
            sum = sum + dat[i] - '0';
        }
        return sum;
    }
    //有小数点
    if (i < count)
    {
        //计算整数部分
        for (j = 0; j < i; j++)
        {
            sum = sum * 10;
            sum = sum + dat[j] - '0';
        }
        //计算小数部分
        for (++j; j < count; j++)
        {
            sum = sum + (dat[j]-'0') * PowFloat( j-i);
        }
        return sum;
    }
    return -1;
}

void ConvertionSuffixExpression(char *str, stack &st)
{
    char count,flag;
    char dat[MAXSIZEOFDATA];
    stack buffer;
    typedata  sum;
    flag = 0;
    StackInit(buffer);
    while (*str != '\0'||*str=='\n')
    {
        count = 0;
        //检测含字符串  是否有可能是计算数据
        while ( (*str) <= '9' &&(*str) >= '0'||*str=='.')
        {
            //防止野指针的产生
            if (*str == '\0' || *str == '\n')
            {
                //标志位  字符串使用已经结束
                flag = 1;
                break;
            }
            dat[count++] = *str;
            str++;
        }
        //获数字
        if (count)
        {
            sum = StringToData(dat, count);
            StackPush(st, sum, IsData);
        }
        //标志位  字符串使用已经结束
        if (flag==1||*str=='\0')
            break;
        //左括号直接进栈
        if (*str == '(')
            StackPush(buffer, *str, IsSymbol);
        else  if (*str==')')//右括号直接退栈  直至遇到左括号
        {
            StackPush(buffer, *str, IsSymbol);
            do
            {
                StackPush(st, StackPop(buffer),IsSymbol);
            } while (buffer.data[buffer.top][0] != '(');
        } //遇到了加减运算
        else  if (*str == '+' || *str == '-')
        {
            if (StackIsEmpty(buffer)==1)
                StackPush(buffer, *str,IsSymbol);
            else if (buffer.data[buffer.top][0] == '+' || buffer.data[buffer.top][0] == '-')
            {
                StackPush(buffer, *str, IsSymbol);
            }
            else if (buffer.data[buffer.top][0] == '/' || buffer.data[buffer.top][0] == '*')
            {
                StackPush(st, StackPop(buffer), IsSymbol);
                StackPush(buffer, *str,IsSymbol);
            }
            else  //栈顶元素为括号
            {
                StackPush(buffer, *str,IsSymbol);
            }
        }
        else  //遇到了乘除运算
        {
            if (StackIsEmpty(buffer)==1)
                StackPush(buffer, *str, IsSymbol);
            else if (buffer.data[buffer.top][0] == '+' || buffer.data[buffer.top][0] == '-')
            {
                StackPush(buffer, *str, IsSymbol);
            }
            else if (buffer.data[buffer.top][0] == '/' || buffer.data[buffer.top][0] == '*')
            {
                StackPush(st, StackPop(buffer), IsSymbol);
                StackPush(buffer, *str, IsSymbol);
            }
            else  //栈顶元素为括号
            {
                StackPush(buffer, *str, IsSymbol);
            }
        }
        str++;
    }
    while (StackIsEmpty(buffer)==0)
    {
        count = StackPop(buffer);
        StackPush(st,count, IsSymbol);
    }
}

void SmartCounter(char *str)
{
    typedata  countleft, countright,count;
    stack dat, counter, draft;
    StackInit(dat);
    StackInit(counter);
    StackInit(draft);
    ConvertionSuffixExpression(str, draft);
    //由于draft中 后缀表达式是反的 因此需要将顺序颠倒一下
    while (StackIsEmpty(draft)==0)
    {
        StackPush(dat, StackPop(draft),draft.data[draft.top][1]);
    }
    //开始正式的计算过程
    while (StackIsEmpty(dat)==0)
    {
        count = StackPop(dat);
        //直接判断是不是计算数据
        if (dat.data[dat.top+1][1]==IsData)
        {
            StackPush(counter, count,IsData);
        }//不是数据那么就是运算符了
        else if (count == '+' || count == '-' || count == '*' || count == '/')
        {
            countright = StackPop(counter) ;
            countleft = StackPop(counter);
            if (count == '+')
            {
                count = countleft + countright;
                StackPush(counter, count,IsData);
            }
            else if (count == '-')
            {
                count = countleft - countright ;
                StackPush(counter, count, IsData);
            }
            else if (count == '*')
            {
                count = countleft * countright;
                StackPush(counter, count, IsData);
            }
            else if (count == '/')
            {
                count = countleft / countright;
                StackPush(counter, count, IsData);
            }
        }
        else{}
    }
    while (StackIsEmpty(counter)==0)
    {
        cout << "您输入的算术表达式为: \n"<<str << endl;
        cout << "计算结果为\n" << StackPop(counter) << endl;
    }
}

void main()
{
    char str[MAXSIZE];
    DWORD  t1, t2;
    t1 = GetTickCount();
    cout << "请输入计算式" << endl;
    cin >> str;
    SmartCounter(str);
    t2 = GetTickCount();
    cout << "本次计算用时:"<<(double)t2-t1<<"ms" << endl;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值