表达式计算器——利用栈的原理

回家前写一下的小程序:就是先自己写一个栈,再讲这个栈来作为自己所写的类Calculator的一个成员,然后再输出结果。

写完之后想一下,配合高精度运算应该会很屌,但由于写完的时候已经2点了,所以,以后有机会的话就po上来吧。

实验要求:

一、问题描述

利用栈原理对表达式进行转换,变成后缀表达式,再运用出栈入栈的优先性进行表达式的运算。

二、基本要求

1.能对表达式进行基本的运算。

2.对栈的设定有初步认识。

3.能对结果或者栈运行进行发现错误。

4排错,检测函数,以保证栈正常运行。

三、概要设计

1.数据结构设计。

实验中,对栈类中函数的设定有通常几种基本函数,比如栈空,输入,输出等,这些都是栈对表达式进行运算的基本工具

还有几个排错,检测的函数,以保证栈正常运行。

四、运行与测试

1、在调试中,发现后面几个检测函数有一定语言难度,进行再挖掘,整理好逻辑关系。

 

以下是源代码:

STACK_H.h:

#ifndef Stack_H
#define Stack_H

template<typename T>
class Stack
{
public:
 Stack();
 bool empty();
 T top();
 void push(T value);
 T pop();
 int getSize();

private:
 T *element;
 int size;
 int capacity;
 void ensureCapacity();
};

//构造函数
template<typename T>
Stack<T>::Stack():size(0),capacity(16){
 element =  new T[capacity];
}

//判断栈是否为空
template<typename T>
bool Stack<T>::empty()
{
 return (size==0);
}

//返回栈的顶端
template<typename T>
T Stack<T>::top()
{
 return element[size-1];
}

//压栈操作
template<typename T>
void Stack<T>::push(T value)
{
 ensureCapacity();
 element[size++]=value;
}

//确保栈的容量够大,不会出现溢出的情况
template<typename T>
void Stack<T>::ensureCapacity()
{
 if(size >= capacity)
 {
  T * old = element;
  capacity = 2 * size;
  element = new T[size*2];

  for(int i = 0;i < size ;i++)
   element[i] = old[i];
  delete old;
 }
}

//出栈操作
template<typename T>
T Stack<T>::pop()
{
 return element[--size];
}

//返回栈的容量
template<typename T>
int Stack<T>::getSize()
{
 return size;
}

#endif

 Calculator.h:

#ifndef Calculator_H
#define Calculator_H

#include <string>
#include <stdlib.h>
#include "STACK_H.h"
using namespace std;

class Calculator
{
public:
 Calculator();
 Calculator(string a);
 string change();
 double result();

private:
 Stack<int> stack;
 string expression;
};

Calculator::Calculator():stack(),expression(NULL){}

Calculator::Calculator(string a):stack(),expression(a){}


//将相应的后缀表达式转化为中缀表达式
string Calculator::change()
{
 int i;
    string tt;
    for(i = 0 ; i < expression.length() ; i++ )
    {
        if(expression[i] >= '0' && expression[i] <= '9')
        {
            tt += expression[i];
        }
        else if(expression[i] == '+' || expression[i] == '-')
        {
            if(stack.empty() || stack.top() == '(')
                stack.push(expression[i]);
            else if(stack.top() == '+' || stack.top() == '-')
            {
                tt += stack.top();
                stack.pop();
                stack.push(expression[i]);
            }
            else if(stack.top() == '*' || stack.top() == '/' )
            {
                tt += stack.top();
                stack.pop();
                if(!stack.empty())
                {
                    tt += stack.top();
                    stack.pop();
                }
                stack.push(expression[i]);
   }
        }
        else if(expression[i] == '*' || expression[i] == '/' )
        {
            if(stack.empty() || stack.top() == '(')
                stack.push(expression[i]);
            else if(stack.top() == '*' || stack.top() == '/' )
            {
                tt += stack.top();
                stack.pop();
                stack.push(expression[i]);
            }
            else if(stack.top() == '+' || stack.top() == '-')
            {
                stack.push(expression[i]);
            }
        }
        else if(expression[i] == '(')
        {
            stack.push(expression[i]);
        }
        else if(expression[i] == ')')
        {
            while(stack.top() != '(' )
            {
                tt += stack.top();
                stack.pop();
            }
                stack.pop();
        }

    }
    while(!stack.empty())
    {
        tt += stack.top();
        stack.pop();
    }
    return tt;
}

//将后缀表达式计算出先应的答案
double Calculator::result()
{
 string cc = change();
 Stack<double> temp;
 int i ;
 
    for(i = 0; i < cc.length() ; i++)
    {
        if(cc[i] >= '0' && cc[i] <= '9')
  {
   temp.push(cc[i] - '0');
  }
  else if(cc[i] == '+')
        {
            double a,b;
            a = temp.top();
            temp.pop();
            b = temp.top();
            temp.pop();
            temp.push(a + b);
        }
        else if(cc[i] == '-')
        {
            double a,b;
            a = temp.top();
            temp.pop();
            b = temp.top()  ;
            temp.pop();
            temp.push(b - a);
        }
        else if(cc[i] == '*')
        {
            double a,b;
            a = temp.top();
            temp.pop();
            b = temp.top();
            temp.pop();
            temp.push(a * b);
        }
        else if(cc[i] == '/')
        {
            double a,b;
            a = temp.top();
            temp.pop();
            b = temp.top()  ;
            temp.pop();
   //看分母是否为0,若是,则抛出异常
   try
   {
    if(a==0)
     throw b;
    temp.push(b / a);
   }
   catch(int b)
   {
    cout << "Exception: an inter " << b << "cannot be divided by zero" << endl;
   }
  }
    }
    return temp.top();
}


#endif

test.cpp:

#include <iostream>
#include "STACK_H.h"
#include "Calculator.h"
using namespace std;
int main()
{
 string ss;
 cin >> ss;
 Calculator bb(ss);
 cout<<bb.result()<<endl;
}


 

转载于:https://www.cnblogs.com/sysu-blackbear/archive/2013/01/26/2877479.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值