🎈 作者:Linux猿
🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!
🎈 关注专栏: 数据结构和算法成神路【精讲】优质好文持续更新中……🚀🚀🚀
🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬
目录
一、整体思路
二、思路解析
2.1 类设计
2.2 界面设计
2.3 表达式计算
三、计算器源码
四、总结
本篇文章使用 C++ 实现了一个简单的计算器,支持基本运算加减乘除,下面来详细讲解下 C++ 计算器的制作过程!
首先,先来看一下效果图:

一、整体思路
整体的设计包含两个部分:界面的设计和表达式的计算。设计流程图如下所示:

二、思路解析
2.1 类设计
计算器类的设计如下所示:
/**
* C++ 整数计算器
*/
class SimpleCalculator {
public:
SimpleCalculator() {
m['+'] = 1;
m['-'] = 1;
m['*'] = 2;
m['/'] = 2;
m['('] = 0;
error = false;
}
//初始化操作
void init() {
system("chcp 65001"); //语言支持
system("mode con cols=90 lines=30");//设置终端大小
system("cls");
}
int calaulator(); //计算表达式
int solve(int x,int y,char c);
void hideCursor(); //隐藏光标
void getCoord(int x, int y); //光标重定位,用于在光标处输出
void color(int a); //设置颜色
void menu();
bool isLegal(char ch);
void printEdge();
private:
string expStr;
bool error;
stack<int> s1; //存储数字
stack<char> s2; //存储符号
map<int,int> m; //定义符号优先级
};
2.2 界面设计
界面的设计主要是主菜单的输出,实现如下所示:
//菜单
void SimpleCalculator::menu() {
system("cls"); //清屏
hideCursor();
while(true) {
system("cls"); //清屏
printEdge();
getCoord(55, 5); color(6); cout<<"计 算 器"; color(7);
getCoord(28, 22); color(2); cout<<"说明:清除表达式请按 c 或 enter "; color(7);
getCoord(28, 16); color(9); cout<<"计 算 结 果 :"; color(7);
getCoord(28, 12); color(9); cout<<"请输入表达式:"; color(7);
cin>>expStr;
int ans = calaulator();
if (!error) {
getCoord(28, 16); color(9); cout<<"计 算 结 果 :"; color(7); cout<<"表达式错误!"; color(7);
} else {
getCoord(28, 16); color(9); cout<<"计 算 结 果 :"; color(7); cout<<ans; color(7);
}
while (true) {
char ch = _getch();//选择
if (ch == 'c' || ch == '\r') {
break;
}
}
}
}
2.3 表达式计算
输入表达式的计算通过使用两个栈,一个存储数字,一个存储字符,如下所示:
//计算表达式
int SimpleCalculator::calaulator() {
int len = expStr.size();
int i = 0;
error = true;
while (i < len) {
if (!isLegal(expStr[i])) {
error = false;
return -1;
}
if(expStr[i] >= '0' && expStr[i] <= '9') { // 如果是数字
int num = 0;
while (expStr[i] >= '0' && expStr[i] <= '9'){
num = num * 10 + expStr[i] -'0';
i++;
}
s1.push(num);
} else {
if (expStr[i] == '('){
s2.push(expStr[i]);
} else if (expStr[i] == ')') {
if(!s2.size()) {
error = false;
return -1;
}
while (s2.top() != '(') {
char ch = s2.top();
s2.pop();
if(!s1.size()) {
error = false;
return -1;
}
int x = s1.top();
s1.pop();
if(!s1.size()) {
error = false;
return -1;
}
int y = s1.top();
s1.pop();
s1.push(solve(y, x, ch));
}
s2.pop();
} else {
while(s2.size() && m[s2.top()] >= m[expStr[i]]){
char ch = s2.top();
s2.pop();
if(!s1.size()) {
error = false;
return -1;
}
int x = s1.top();
s1.pop();
if(!s1.size()) {
error = false;
return -1;
}
int y = s1.top();
s1.pop();
s1.push(solve(y, x, ch));
}
s2.push(expStr[i]);
}
i++;
}
}
//判断是否还有剩余的表达式
while (s2.size()){
char ch = s2.top();
s2.pop();
if(!s1.size()) {
error = false;
return -1;
}
int x = s1.top();
s1.pop();
if(!s1.size()) {
error = false;
return -1;
}
int y = s1.top();
s1.pop();
s1.push(solve(y, x, ch));
}
if (s2.size()) {
error = false;
}
return s2.size() ? -1 : s1.top();
}
主要原理是通过两个栈,一个存储数字,一个存储字符,根据运算符优先级模拟表达式的计算,最后注意查看栈中是否还有剩余的表达式。
如果表达式正确,返回表达式计算的值,否则返回 -1。
三、计算器源码
下面是C++计算器源码实现,如下所示:
#include <iostream>
#include <stack>
#include <string.h>
#include <map>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
using namespace std;
/**
* C++ 整数计算器
*/
class SimpleCalculator {
public:
SimpleCalculator() {
m['+'] = 1;
m['-'] = 1;
m['*'] = 2;
m['/'] = 2;
m['('] = 0;
error = false;
}
//初始化操作
void init() {
system("chcp 65001"); //语言支持
system("mode con cols=90 lines=30");//设置终端大小
system("cls");
}
int calaulator(); //计算表达式
int solve(int x,int y,char c);
void hideCursor(); //隐藏光标
void getCoord(int x, int y); //光标重定位,用于在光标处输出
void color(int a); //设置颜色
void menu();
bool isLegal(char ch);
void printEdge();
private:
string expStr;
bool error;
stack<int> s1; //存储数字
stack<char> s2; //存储符号
map<int,int> m; //定义符号优先级
};
//设置颜色
void SimpleCalculator::color(int a)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
}
//光标重定位,用于在光标处输出
void SimpleCalculator::getCoord(int x, int y)
{
COORD pos = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
//隐藏光标
void SimpleCalculator::hideCursor()
{
CONSOLE_CURSOR_INFO cursor= { 1, 0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);
}
//进行计算
int SimpleCalculator::solve(int x, int y, char c){
int ret = 0;
if (c == '*') {
ret = x*y;
} else if (c == '/'){
ret = x/y;
} else if (c == '+'){
ret = x+y;
} else if (c == '-'){
ret = x-y;
}
return ret;
}
//判断字符是否合法
bool SimpleCalculator::isLegal(char ch) {
if (ch >= '0' && ch <= '9') {
return true;
}
if (ch == '*' || ch == '/' || ch == '+' || ch == '-') {
return true;
}
if (ch == '(' || ch == ')') {
return true;
}
return false;
}
//计算表达式
int SimpleCalculator::calaulator() {
int len = expStr.size();
int i = 0;
error = true;
while (i < len) {
if (!isLegal(expStr[i])) {
error = false;
return -1;
}
if(expStr[i] >= '0' && expStr[i] <= '9') { // 如果是数字
int num = 0;
while (expStr[i] >= '0' && expStr[i] <= '9'){
num = num * 10 + expStr[i] -'0';
i++;
}
s1.push(num);
} else {
if (expStr[i] == '('){
s2.push(expStr[i]);
} else if (expStr[i] == ')') {
if(!s2.size()) {
error = false;
return -1;
}
while (s2.top() != '(') {
char ch = s2.top();
s2.pop();
if(!s1.size()) {
error = false;
return -1;
}
int x = s1.top();
s1.pop();
if(!s1.size()) {
error = false;
return -1;
}
int y = s1.top();
s1.pop();
s1.push(solve(y, x, ch));
}
s2.pop();
} else {
while(s2.size() && m[s2.top()] >= m[expStr[i]]){
char ch = s2.top();
s2.pop();
if(!s1.size()) {
error = false;
return -1;
}
int x = s1.top();
s1.pop();
if(!s1.size()) {
error = false;
return -1;
}
int y = s1.top();
s1.pop();
s1.push(solve(y, x, ch));
}
s2.push(expStr[i]);
}
i++;
}
}
//判断是否还有剩余的表达式
while (s2.size()){
char ch = s2.top();
s2.pop();
if(!s1.size()) {
error = false;
return -1;
}
int x = s1.top();
s1.pop();
if(!s1.size()) {
error = false;
return -1;
}
int y = s1.top();
s1.pop();
s1.push(solve(y, x, ch));
}
if (s2.size()) {
error = false;
}
return s2.size() ? -1 : s1.top();
}
//打印边框
void SimpleCalculator::printEdge() {
int x = 10, y = 2;
for(int i = x; i <= 110; ++i) {
getCoord(i, y); color(4); cout<<"=";
}
x = 10, y = 28;
for(int i = x; i <= 110; ++i) {
getCoord(i, y); color(4); cout<<"=";
}
x = 10, y = 3;
for(int i = y; i <= 27; ++i) {
getCoord(x, i); color(4); cout<<"||";
}
x = 109, y = 3;
for(int i = y; i <= 27; ++i) {
getCoord(x, i); color(4); cout<<"||";
}
}
//菜单
void SimpleCalculator::menu() {
system("cls"); //清屏
hideCursor();
while(true) {
system("cls"); //清屏
printEdge();
getCoord(55, 5); color(6); cout<<"计 算 器"; color(7);
getCoord(28, 22); color(2); cout<<"说明:清除表达式请按 c 或 enter "; color(7);
getCoord(28, 16); color(9); cout<<"计 算 结 果 :"; color(7);
getCoord(28, 12); color(9); cout<<"请输入表达式:"; color(7);
cin>>expStr;
int ans = calaulator();
if (!error) {
getCoord(28, 16); color(9); cout<<"计 算 结 果 :"; color(7); cout<<"表达式错误!"; color(7);
} else {
getCoord(28, 16); color(9); cout<<"计 算 结 果 :"; color(7); cout<<ans; color(7);
}
while (true) {
char ch = _getch();//选择
if (ch == 'c' || ch == '\r') {
break;
}
}
}
}
//主函数
int main(){
SimpleCalculator obj;
obj.menu();
return 0;
}
四、总结
计算器的实现的重点在输入表达式的计算,通过两个栈,一个存储字符,一个存储输入的数字,实现了对表达式的计算。
⭐优质专栏推荐⭐
数据结构和算法成神路【精讲】
C/C++面试通关【精讲】
Linux技术和原理
🎈 感觉有帮助记得「一键三连」支持下哦!有问题可在评论区留言💬,感谢大家的一路支持!🤞猿哥将持续输出「优质文章」回馈大家!🤞🌹🌹🌹🌹🌹🌹🤞