您的位置:首页 > 其它

基于堆栈的计算器

2016-12-21 10:39 344 查看
简单的基于堆栈的计算器

(1)接受用户的输入,输入形式有两种:数字、运算符。

(2)数字保存在堆栈中(LIFO类型内存),将数字推入堆栈。

(3)对堆栈顶端的两个数字出栈,应用运算符,若堆栈只有一个数字,将它重复,应用运算符。将计算结果,压入堆栈。

(4)使用逆波兰表示法(后缀法),例:“4+5”等价于“4 5 +”、“4+5-2”等价于“4 5 + 2 -

(5)实现4种运算”+ - * /“

设计(自顶向下)

(1)计算器对象为顶层对象。

(2)计算器使用堆栈保存了输入的数字,并对这些数字应用运算符。

(3)每次输入后,使用堆栈序列生成器,显示此时堆栈的内容。

(4)使用输入对象进行一些预处理(判别数字、运算符、非法输入),将用户输入的内容传递给计算器对象

(5)输入对象从标准输入获得一个字符串,区别是数字还是运算符。如果是数字,将字符串转为数字,交给计算器对象压入堆栈。如果是运算符,交给计算器对象,实现此运算。

(6)计算器对象对堆栈每次操作后,使用堆栈序列生成器,输入堆栈当前内容。

具体实现

main.cpp

#include<iostream>
#include"calc.h"
int main()
{
//计算器对象
Calculator TheCalculator;
//迭代状态
bool status;
do
{
std::cout << "> ";
//输入对象
Input input;
status = TheCalculator.Execute(input);
if (status)
{
for (StackSeq seq(TheCalculator.GetStack());//堆栈序列对象
!seq.AtEnd();
seq.Advance())
{
//输入堆栈内容
std::cout << " " << seq.GetNum() << std::endl;
}
}
} while (status);
}


计算器类

calc.h

#ifndef CALC_H
#define CALC_H
#include<iostream>
#include<cassert>
#include"input.h"
#include"stack.h"
class Calculator
{
public:
//int const 等价于 const int
bool Execute(Input const & input);
//堆栈常量的引用(只读)
IStack const & GetStack()
{
return _stack;
}
private:
//堆栈(嵌入对象)
IStack _stack;
//计算函数
int Calculate(int num1, int num2, int token)const;
};
#endif


calc.cpp

#include"calc.h"

bool Calculator::Execute(Input const &input)
{
//获得input对象的输入
int token = input.Token();
//初始时假定失败
bool status = false;

//错误
if (token == tokError)
{
std::cout << "Unknown token\n";
}
//输入为数字
else if (token == tokNumber)
{
if (_stack.IsFull())
{
std::cout << "Stack is full";
}
else
{
_stack.Push(input.Number());
status = true;
}
}
//输入为运算符号
else
{
//契约:input不能产生任何其他字符
assert(token == '+' || token == '-' || token == '*'
|| token == '/');
//堆栈空
if(_stack.IsEmpty())
{
std::cout << "Stack is empty" << std::endl;
}
else
{
int num2 = _stack.Pop();
int num1;
//当堆栈只有一个数
if (_stack.IsEmpty())
{
num1 = num2;
}
else
{
num1 = _stack.Pop();
}
//结果Push堆栈
_stack.Push(Calculate(num1, num2, token));
status = true;
}
}
return status;
}
int Calculator::Calculate(int num1, int num2, int token) const
{
int result;
if (token == '+')
result = num1 + num2;
else if (token == '-')
result = num1 - num2;
else if (token == '*')
result = num1 * num2;
else if (token == '/')
{
if (num2 == 0)
{
std::cout << "Division by zero" << std::endl;
result = 0;
}
else
result = num1/num2;
}
return result;
}


堆栈与堆栈序列生成器

stack.h

#ifndef STACK_H
#define STACK_H
#include<iostream>
#include<cassert>
const int maxStack = 16;
//堆栈类
class IStack
{
friend class StackSeq;
public:
IStack() :_top(0){}
void Push(int i);
int Pop();
//堆栈满
bool IsFull();
//堆栈空
bool IsEmpty();
private:
//实际数据类型 整型数组
int _arr[maxStack];
int _top;
};
//堆栈序列生成器类
class StackSeq
{
public:
StackSeq(IStack const & stack) :_stack(stack), _iCur(0){}
//是否到达堆栈尾端
bool AtEnd();
//堆栈当前索引内容
int GetNum();
//下一个索引
void Advance();
private:
//堆栈常量的引用
IStack const & _stack;
int _iCur;
};

#endif


stack.cpp

#include"stack.h"

void IStack::Push(int i)
{
assert(_top < maxStack);
_arr[_top] = i;
_top++;
}
int IStack::Pop()
{
assert(_top>0);
--_top;
return _arr[_top];
}
bool IStack::IsFull()
{
if (_top < maxStack)
{
return false;
}
else
{
return true;
}
}
bool IStack::IsEmpty()
{
if (_top > 0)
{
return false;
}
else
{
return true;
}
}
bool StackSeq::AtEnd()
{
return  _iCur==_stack._top;
}
void StackSeq::Advance()
{
assert(!AtEnd());
++_iCur;
}
int StackSeq::GetNum()
{
assert(!AtEnd());
return _stack._arr[_iCur];
}


输入类

input.h

#ifndef INPUT_H
#define INPUT_H
#include<iostream>
#include<cctype>
#include<cassert>
#include<cstdlib>
const int maxBuf = 100;
const int tokNumber = 1;
const int tokError = 2;

class Input
{
public:
Input();
//将输入返回给计算器对象
int Token()const{ return _token; }
//字符串转数字
int Number()const;
private:
int _token;
char _buf[maxBuf];
};
#endif


input.cpp

#include"input.h"

Input::Input()
{
std::cin >> _buf;
int c = _buf[0];
if (std::isdigit(c))
_token = tokNumber;
else if (c == '+' || c == '*' || c == '/')
_token = c;
//允许输入负数
else if (c == '-')
{
if (std::isdigit(_buf[1]))
_token = tokNumber;
else
_token = c;
}
else
_token = tokError;
}
int Input::Number()const
{
assert(_token == tokNumber);
return std::atoi(_buf);
}


运行效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息