来源:微信公众号「编程学习基地」
推荐指数:?????
C++简易计算器
效果展示
源码获取:关注微信公众号编程学习基地,后台发送关键字计算器获取
栈
栈(Stack)的特点
(1)栈中的数据元素遵守“先进后出"(First In Last Out)的原则,简称FILO结构。(后进先出的叫法,也是可以的)
(2)限定只能在栈顶进行插入和删除操作。
栈的相关概念
(1)栈顶与栈底:允许元素插入与删除的一端称为栈顶,另一端称为栈底。
(2)压栈:栈的插入操作,叫做进栈,也称压栈、入栈。
(3)弹栈:栈的删除操作,也叫做出栈。
栈的常用操作为
(1)弹栈,通常命名为pop
(2)压栈,通常命名为push
(3)求栈的大小
(4)判断栈是否为空
(5)获取栈顶元素的值
栈的常见分类
(1)基于数组的栈——以数组为底层数据结构时,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向
(2)基于单链表的栈——以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部
实例
模仿std::stack创建一个模板类
实现栈的基本功能:
public:
void clear();
void push(T t);
T pop();
T top();
public:
int size();
bool empty();
完整代码展示
#pragma once
template<typename T>
struct Node
{
T m_value;
Node<T>* pNext;
Node() :pNext(nullptr){}
Node(T t) :m_value(t), pNext(nullptr) {}
};
template<typename T>
class Stack
{
int m_length;
Node<T>* pHead;
public:
Stack();
~Stack();
public:
void clear();
void push(T t);
T pop();
T top();
public:
int size();
bool empty();
};
template<typename T>
Stack<T>::Stack()
{
m_length = 0;
pHead = new Node<T>;
}
template<typename T>
Stack<T>::~Stack()
{
clear();
}
template<typename T>
void Stack<T>::clear()
{
while (pHead->pNext != nullptr)
{
Node<T> *temp = pHead->pNext;
pHead->pNext = temp->pNext;
delete temp;
}
}
template<typename T>
void Stack<T>::push(T t)
{
Node<T> *pNode = new Node<T>(t);
pNode->pNext = pHead->pNext;
pHead->pNext = pNode;
m_length++;
}
template<typename T>
T Stack<T>::pop()
{
if (pHead->pNext != nullptr)
{
Node<T>* temp = pHead->pNext;
pHead->pNext = temp->pNext;
T popVal = temp->m_value;
delete temp;
m_length--;
return popVal;
}
}
template<typename T>
T Stack<T>::top()
{
if (pHead->pNext != nullptr)
{
return pHead->pNext->m_value;
}
}
template<typename T>
int Stack<T>::size()
{
return m_length;
}
template<typename T>
bool Stack<T>::empty()
{
if (pHead->pNext != nullptr)
return false;
return true;
}
计算器
利用栈实现简易计算器
概念
假设有这样一个表达式
2+3*2+2*(2*2+3)
由于在数学的算式中乘除的优先于加减运算,所以我们必须要把两个相邻的加或减之间的数字或者乘除算式看成一个项,最后再对所有项(term)进行加减操作。为了简单化,这里不考虑计算负数.
上述表达式里面,()里面看成一个项,假设为X;
X里面又分为两个项2*2(假设为X1),X1+3
在()外面3*2是一个项(假设为Y),
2*X又是一个项(假设为Z)
综合起来就是2+Y+Z
怎么判断是一个项呢,左( 到右 )是一个项,±之前的为一个项
代码实现
#pragma once
#include "Stack.h"
#include <string>
using namespace std;
class Calc
{
string str;
Stack<int> digit;
Stack<char> op;
public:
Calc();
~Calc();
public:
int getResult(string Str);
private:
void setStr(string Str);
bool isCalc(char ch);
void Calculation();
};
给外部一个接口,getResult(),其他的内部实现
#include "Calc.h"
Calc::Calc()
{
digit.clear();
op.clear();
}
Calc::~Calc()
{
digit.clear();
op.clear();
}
int Calc::getResult(string Str)
{
setStr(Str);
int temp = 0;
for (unsigned int i = 0; i < str.length(); i++)
{
if (isdigit(str[i]))
{
temp = temp * 10 + str[i] - '0';
if (i + 1 == str.length() || !isdigit(str[i + 1]))
{
digit.push(temp);
temp = 0;
}
}
else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
{
if (isCalc(str[i]))
Calculation();
op.push(str[i]);
}
else if (str[i] == '(') {
op.push(str[i]);
}
else if (str[i] == ')') {
while (op.top() != '(')
Calculation();
op.pop();
}
}
while (!op.empty())
Calculation();
return digit.pop();
}
void Calc::setStr(string Str)
{
this->str = Str;
digit.clear();
op.clear();
}
bool Calc::isCalc(char ch)
{
if (op.empty())
return false;
if (op.top() == '(')
return false;
if (ch == '+' || ch == '-')
return true;
if (ch == '*' && (op.top() == '*' || op.top() == '/'))
return true;
if (ch == '/' && (op.top() == '*' || op.top() == '/'))
return true;
return false;
}
void Calc::Calculation()
{
if (!digit.size()) {
printf("表达式输入错误\n");
system("pause");
exit(0);
}
int right = digit.pop();
if (!digit.size()) {
printf("表达式输入错误\n");
system("pause");
exit(0);
}
int left = digit.pop();
int result;
switch (op.pop())
{
case '+':
result = left + right;
break;
case '-':
result = left - right;
break;
case '*':
result = left * right;
break;
case '/':
{
if (right == 0) {
printf("分母不能为0\n");
system("pause");
exit(0);
}
result = left / right;
}
break;
}
digit.push(result);
}
测试
#include"Stack.h"
#include"Calc.h"
#include <iostream>
#include<conio.h>
using namespace std;
void introduce();
int main()
{
string calc_str;
Calc calc;
while (1)
{
system("cls");
introduce();
cin >> calc_str;
int result = calc.getResult(calc_str);
cout <<"\t"<<calc_str << "=" << result << endl;
cout << "\t按任意键返回" << endl;
getch();
}
cin.get();
cin.get();
return 0;
}
void introduce()
{
printf("\n");
printf("\t╭ ⺌ % ╮ ╭ ```╮ \n");
printf("\t(@^o^@) C++简易计算器 (⌒:⌒)\n");
printf("\t(~):(~) (~)v(~) \n");
printf("\n\n");
cout << "\t来源:微信公众号【编程学习基地】\n\t作者:梦凡\n" << endl;
cout << "\t请输入表达式,例如“2+3*2+2*(2*2+3)”:";
}
结果:
因为催的急,所以如有解释不清楚的我很抱歉,这个只是简易计算器
https://www.cnblogs.com/lulipro/p/7450886.html
|