C++实现简单计算器

 更新时间:2020年05月18日 09:50:56   作者:时光丨荏苒  
这篇文章主要为大家详细介绍了C++实现简单计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现简单计算器的具体代码,供大家参考,具体内容如下

工具

  • stack
  • map

步骤

  • 初始化
  • 读取字符串
  • 去空格
  • 负号处理
  • 判断为空
  • 检查格式
  • 计算

示例

代码

#include <iostream>
#include <string>
#include <stdio.h>
#include <stack>
#include <map>
#include <math.h>
#include <stdlib.h>
#include <sstream>
using namespace std;

char op[8][8];
map<char, int> m;
void init()
{
 m['+'] = 1, m['-'] = 2, m['*'] = 3, m['/'] = 4, m['('] = 5, m[')'] = 6, m['#'] = 7;
 op[1][1] = '>', op[1][2] = '>', op[1][3] = '<', op[1][4] = '<', op[1][5] = '<', op[1][6] = '>', op[1][7] = '>';
 op[2][1] = '>', op[2][2] = '>', op[2][3] = '<', op[2][4] = '<', op[2][5] = '<', op[2][6] = '>', op[2][7] = '>';
 op[3][1] = '>', op[3][2] = '>', op[3][3] = '>', op[3][4] = '>', op[3][5] = '<', op[3][6] = '>', op[3][7] = '>';
 op[4][1] = '>', op[4][2] = '>', op[4][3] = '>', op[4][4] = '>', op[4][5] = '<', op[4][6] = '>', op[4][7] = '>';
 op[5][1] = '<', op[5][2] = '<', op[5][3] = '<', op[5][4] = '<', op[5][5] = '<', op[5][6] = '=';
 op[6][1] = '>', op[6][2] = '>', op[6][3] = '>', op[6][4] = '>', op[6][6] = '>', op[6][7] = '>';
 op[7][1] = '<', op[7][2] = '<', op[7][3] = '<', op[7][4] = '<', op[7][5] = '<', op[7][7] = '=';
}
double operate(double num1, char oper, double num2)
{ 
 if(oper == '+')
 return num1 + num2;
 if(oper == '-')
 return num1 - num2;
 if(oper == '*')
 return num1 * num2;
 if(oper =='/')
 return num1 / num2;
}
string trim(string str)
{
 index = 0;
 if(!str.empty()){
 while((index = str.find(' ',index) != string::nops)
 str.erase(index,1);
 }
 return str;
}
string change(string str)
{
 int start;
 start += "#";
 for(int i = 0; i < str.length(); i++){
 if(str[i] == '-'){
 if(i == 0 || i != 0 && (m[str[i-1]] >= 1 && m[str[i-1]] <= 5
 && str[i+1] >= '0' && str[i+1] <= '9'){
 str += " ";
 int j = i+1;
 start = j;
 while(m[str[j]] == 0)
 j++;
 
 for(int k = str.length() - 1; k >= j; k--)
 str[k] = str[k-3];
 
 str[i] = '(', str[i+1] = '0', str[i+2] = '-';
 
 int l = i+3;
 string s = str.substr(start, j - start);
 for(int k = 0; k < s.length(); k++)
 str[l+k] = s[k];
 
 str[l+s.length()] = ')';
 } 
 }
 }
 str.erase(str.length()-1, 1);
 return str;
}
bool test(string str)
{
 bool ifOK = true;
 int flag = 0;
 stack<char> s;
 int start, e;
 str += "#";
 for(int i = 0; i < str.length(); i++){
 //判断非法字符
 if((str[i] < '0' || str[i] > '9') && m[str[i]] == 0 && str[i] != '.')
 return false;
 if(str[i] == '#' && i!= str.length()-1)
 return false;

 //判断小数点
 if(m[str[i]] == 0){
 if(flag == 0){
 start = i;
 flag = 1;
 }
 }
 if(m[str[i]] != 0){
 if(flag == 1){
 e = i;
 string st = str.substr(start, e - start);
 int pointNum = 0;
 if(st[0] == '.') return false;
 for(int j = 0; j < st.length(); j++){
 if(st[j] == '.') pointNum++;
 }
 if(pointNum > 1) return false;
 
 }
 flag = 0;
 }

 //判断运算符
 if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/'){
 if(i == 0) return false;
 if((str[i-1] < '0' || str[i-1] > '9') && str[i-1] != ')') return false;
 if((str[i+1] < '0' || str[i+1] > '9') && str[i+1] != '(') return false;
 }

 //判断括号
 if(str[i] == '(')
 s.push(str[i]);
 if(str[i] == ')'){
 if(s.empty()) return false;
 char c = s.top();
 if(c == '(')
 s.pop();
 else
 return false;
 }
 }
 //判断括号
 if(!s.empty())
 ifOK = false;
 return ifOK;

}

void caculate(string str)
{
 str += "#";
 int flag = 0;
 int start, e;
 stack<double> numStack;//操作数栈
 stack<char> operStack;//运算符栈
 operStack.push('#');
 int i = 0;

 while(str[i] != '#' || operStack.top() != '#'){
 if(m[str[i]] == 0){
 if(flag == 0){
 start = i;
 flag = 1;
 }
 }
 else{
 if(flag == 1){
 e = i;
 //string 转 double
 stringstream s (str.substr(start, e - start));
 double num;
 s >> num;
 
 numStack.push(num);
 flag = 0;
 }
 char c = operStack.top;
 if(op[m[c]][m[str[i]]] == '<'){
 operStack.push(str[i]);
 i++;
 }
 else if(op[m[c]][m[str[i]]] == '='){
 operStac.pop();
 i++;
 }
 else{
 char oper = operStack.top();
 operStac.pop();
 double num2 = numStack.top();
 numStack.pop();
 double num1 = numStack.top();
 numStack.pop();
 double result = operate(num1, oper, num2);
 numStack.push(result);
 }
 }
 
 }
 printf("\t\t\t= %f\n",numStack.top());
 
}
int main()
{
 init();//初始化
 printf("\n\n\n\t\t\t请输入表达式, 退出请输入end:\n");
 string s;
 getline(cin, s, "\n");//读取字符串
 s = trim(s);//去空格
 s = change(s);//处理负号
 if(s == "end"){
 break;
 }
 else if(s.length() > 0){//判断为空
 if(!test(s))//检查格式
 printf("\t\t\t格式错误\n");
 else
 caculate(s);//计算
 }
 else{
 printf("\t\t\t输入不能为空\n");
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++ Qt开发之使用QNetworkAccessManager实现Web网页访问

    C++ Qt开发之使用QNetworkAccessManager实现Web网页访问

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,本文主要介绍了如何运用QNetworkAccessManager组件实现Web网页访问,需要的可以参考下
    2024-03-03
  • C语言实现一个闪烁的圣诞树

    C语言实现一个闪烁的圣诞树

    本文详细讲解了C语言实现一个闪烁的圣诞树,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • C++代码实现学生信息管理系统

    C++代码实现学生信息管理系统

    这篇文章主要为大家详细介绍了C++代码实现学生信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • 剖析C++中的常量表达式与省略号的相关作用

    剖析C++中的常量表达式与省略号的相关作用

    这篇文章主要介绍了C++中的常量表达式与省略号的相关作用,以及表达式中的可变参数模板示例,需要的朋友可以参考下
    2016-01-01
  • C++实现正态随机分布的方法

    C++实现正态随机分布的方法

    本篇介绍了,使用c++实现正态随机分布的实现方法。需要的朋友参考下
    2013-05-05
  • 如何实现socket网络编程的多线程

    如何实现socket网络编程的多线程

    首先,学好计算机网络知识真的很重要。虽然,学不好不会影响理解下面这个关于宏观讲解,但是,学好了可以自己打渔吃,学不好就只能知道眼前有鱼吃却打不到渔。在Java中网络程序有2种协议:TCP和UDP,下面可以和小编一起学习下
    2019-05-05
  • C语言程序的编译与预处理详解

    C语言程序的编译与预处理详解

    这篇文章主要介绍了C语言程序的编译与预处理,包括介绍了C和C++混合编程的情况,需要的朋友可以参考下,希望能够给你带来帮助
    2021-10-10
  • 深入C中常用的三种排序方法总结以及探讨分析

    深入C中常用的三种排序方法总结以及探讨分析

    本篇文章是对C中常用的三种排序方法总结以及探讨分析的概述,需要的朋友参考下
    2013-05-05
  • C语言用循环单链表实现约瑟夫环

    C语言用循环单链表实现约瑟夫环

    这篇文章主要为大家详细介绍了C语言用循环单链表实现约瑟夫环,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 快速掌握VC6.0中各种宏注释应用(附图)

    快速掌握VC6.0中各种宏注释应用(附图)

    为了方便别人或自己阅读自己的程序,注释是坚决不可少的,一个漂亮的程序,不是在于你应用的技术多么高深,而是能够把高深的技术描述的清楚易懂
    2013-01-01

最新评论