表达式计算器——利用栈的原理
回家前写一下的小程序:就是先自己写一个栈,再讲这个栈来作为自己所写的类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;
}