Calculator

``````// 本程序可以实现实数的加减程序四则运算，支持括号运算符，不支持正负符号！另外Calculator类本身进行了加减乘数输入输出的重载！
//

#include "stdafx.h"
#include<iostream>
#include<functional>  //plus等标准库函数对象
#include<map>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

class Calculator
{
public:
//Calculator(const map<char,function<double(double,double)>> &c):calu(c){}
Calculator() = default;
Calculator(const string &s) :str(s),sum(get_sum(s)) {}

string get_string()const { return str; }

double get_sum(const string &s)
{
if (sum_str(s))
{
str = s;
return get_sum();
}

else
{
throw exception("NO sum!");
}
}
double get_sum()
{
return sum;
}

void operator()()
{
cout << get_sum();
}

friend Calculator operator+(const Calculator &lh, const Calculator &rh);
friend Calculator operator-(const Calculator &lh, const Calculator &rh);
friend Calculator operator*(const Calculator &lh, const Calculator &rh);
friend Calculator operator/(const Calculator &lh, const Calculator &rh);
friend istream& operator>>(istream &in, Calculator &rh);
friend ostream& operator<<(ostream &os, const Calculator &rh);
friend bool operator<(const Calculator &lh, const Calculator &rh);
friend bool operator==(const Calculator &lh, const Calculator &rh);

Calculator operator+=(const Calculator &rh)
{
str = str+"+"+rh.str;
sum = rh.sum + sum;
return  *this;
}

private:
double sum = 0;
string str;
map<string, function<double(double, double)>> calu={ { "+", plus<double>() },{ "-",minus<double>() },{ "*",multiplies<double>() },{ "/",divides<double>() } };// /转义字符如何解决啊？为什么不能设置为static成员！
double sum_str(string s);
};

Calculator operator+(const Calculator &lh, const Calculator &rh)
{
Calculator sum = lh;
sum += rh;
return sum;
}
Calculator operator-(const Calculator &lh, const Calculator &rh)
{
Calculator ret;
ret.str = lh.str + "-(" + rh.str + ")";
ret.sum = lh.sum - rh.sum;
return ret;
}
Calculator operator*(const Calculator &lh, const Calculator &rh)
{
Calculator ret;
ret.str = string("(")+lh.str + ")" + "*(" + rh.str + ")";
ret.sum = lh.sum * rh.sum;
return ret;
}
Calculator operator/(const Calculator &lh, const Calculator &rh)
{
Calculator ret;
if (rh.sum != 0)
{
ret.str = string("(") + lh.str + ")" + "/(" + rh.str + ")";
ret.sum = lh.sum / rh.sum;
return ret;
}
else
throw invalid_argument(to_string(rh.sum));

}
bool operator<(const Calculator &lh, const Calculator &rh)
{
if (lh.sum < rh.sum)
return true;
else
return false;
}
bool operator==(const Calculator &lh, const Calculator &rh)
{
return lh.sum == rh.sum;
}

istream& operator>>(istream &in, Calculator &rh)
{
in >> rh.str;
if (in)
rh.get_sum(rh.str);
return in;
}
ostream& operator<<(ostream &os,const Calculator &rh)
{
os << rh.sum;
return os;
}

double Calculator::sum_str(string s)
{
//size_t cc = 0;
//for (auto r : s)      //for范围需要引用吗？可以引用，可以不引用。引用的时候可以改变字符！

for (size_t i = 0; i < s.size(); i++)
{
if (s[i] == '(')
{
for (size_t j = s.size() - 1; j > i; --j)
{
if (s[j] == ')')
{
bool flag = true;                   //判断（）内部是否还有其他括号
for (size_t k = i+1; k < j; ++k)
{
if (s[k] == '(' || s[k] == ')')
flag = false;
}
if (flag)
{
string tmp1 = s.substr(i + 1, j - i - 1);
auto tmp2 = sum_str(tmp1);
s = s.substr(0, i) + to_string(tmp2) + s.substr(j + 1);
break;
}
}
}
}
}

const string format = "+-*/.0123456789";
for (auto r : s)                        //监测是否含有非法字符？
{
if (format.find(r) == string::npos)
{
throw invalid_argument(s);
}
}

const string format2 = "+-*/";
size_t pos = 0;                 //分接字符串s。（只做四则运算，不包含括号和正负！）
vector<string> tmp;
for (size_t i = 0; i < s.size(); ++i)
{
if (format2.find(s[i]) != string::npos)
{
if (i == pos)                               //如果两个符号相同位置，则将数字置为0.主要应用于（-13）计算！
tmp.push_back(string(1, '0'));
else
tmp.push_back(s.substr(pos, i - pos));
tmp.push_back(string(1, s[i]));
pos = i + 1;
}
}
tmp.push_back(s.substr(pos));       //最后一个数字！

size_t length = tmp.size();
while (length>1)
{
for (size_t i = 0; i < length; ++i)
{
if (tmp[i] == "*" || tmp[i] == "/")
{
auto tmp_0 = stod(tmp[i - 1]);
auto tmp_1 = stod(tmp[i + 1]);
if (tmp[i] == "*")
{
tmp_0=calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0*tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
else
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0/tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
for (size_t j = i; j < (length-3); j=j+2)
{
swap(tmp[j], tmp[j + 2]);
swap(tmp[j + 1], tmp[j + 3]);
}
tmp.pop_back();
tmp.pop_back();
i = i-1;            //移动了vector的元素，所以实时位置i要更改！
length = length - 2;
}
}

for (size_t i = 0; i < length; ++i)
{
if (tmp[i] == "+" || tmp[i] == "-")
{
auto tmp_0 = stod(tmp[i - 1]);
auto tmp_1 = stod(tmp[i + 1]);
if (tmp[i] == "+")
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0+tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
else
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0 - tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
for (size_t j = i; j < (length - 3); j = j + 2)
{
swap(tmp[i], tmp[i + 2]);
swap(tmp[i + 1], tmp[i + 3]);
}
tmp.pop_back();
tmp.pop_back();
length = length - 2;
}
}
}
sum = stod(tmp[0]);
return sum;
}

double sum(string s)
{
map<string, function<double(double, double)>> calu = { { "+", plus<double>() },{ "-",minus<double>() },{ "*",multiplies<double>() },{ "/",divides<double>() } };// /转义字符如何解决啊？为什么不能设置为static成员！
for (size_t i = 0; i < s.size(); i++)
{
if (s[i] == '(')
{
for (size_t j = s.size()-1; j > i; --j)
{
if (s[j] == ')')
{
string tmp1 = s.substr(i + 1, j - i - 1);
auto tmp2 = sum(tmp1);
s = s.substr(0, i) + to_string(tmp2)+s.substr(j+1);
break;
}
}
}
}

const string format = "+-*/.0123456789";
for (auto r : s)                        //监测是否含有非法字符？
{
if (format.find(r) == string::npos)
{
throw invalid_argument(s);
}
}

const string format2 = "+-*/";
size_t pos = 0;                 //分接字符串s。（只做四则运算，不包含括号和正负！）
vector<string> tmp;
for (size_t i = 0; i < s.size(); ++i)
{
if (format2.find(s[i]) != string::npos)
{
if(i==pos)                              //如果两个符号相同位置，则将数字置为0.主要应用于（-13）计算！
tmp.push_back(string(1,'0'));
else
tmp.push_back(s.substr(pos, i - pos));
tmp.push_back(string(1, s[i]));
pos = i + 1;
}
}
tmp.push_back(s.substr(pos));       //最后一个数字！

size_t length = tmp.size();
while (length>1)
{
for (size_t i = 0; i < length; ++i)
{
if (tmp[i] == "*" || tmp[i] == "/")
{
auto tmp_0 = stod(tmp[i - 1]);
auto tmp_1 = stod(tmp[i + 1]);
if (tmp[i] == "*")
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0*tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
else
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0/tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
for (size_t j = i; j < (length - 3); j = j + 2)
{
swap(tmp[j], tmp[j + 2]);
swap(tmp[j + 1], tmp[j + 3]);
}
tmp.pop_back();
tmp.pop_back();
i = i - 1;          //移动了vector的元素，所以实时位置i要更改！类似于迭代器之于容器！
length = length - 2;
}
}

for (size_t i = 0; i < length; ++i)
{
if (tmp[i] == "+" || tmp[i] == "-")
{
auto tmp_0 = stod(tmp[i - 1]);
auto tmp_1 = stod(tmp[i + 1]);
if (tmp[i] == "+")
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0+tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
else
{
tmp_0 = calu[tmp[i]](tmp_0, tmp_1);
//tmp_0 = tmp_0 - tmp_1;
tmp[i - 1] = to_string(tmp_0);
}
for (size_t j = i; j < (length - 3); j = j + 2)
{
swap(tmp[i], tmp[i + 2]);
swap(tmp[i + 1], tmp[i + 3]);
}
tmp.pop_back();
tmp.pop_back();
length = length - 2;
}
}
}
auto su = stod(tmp[0]);
return su;
}

int main()
{
//map<char, function<double(double, double)>> cal = { {'+', plus<double>()},{'-',minus<double>()},{'*',multiplies<double>()},{'/',divides<double>() } };// /转义字符如何解决啊？
/*
Calculator cc;
cout<<cc.get_sum(("1+2*3/3-1*2/2"))<<endl;

Calculator c1("1+4/2*3-1*2");
Calculator c2("1+4/2*3+1*2");

cout << c1.get_sum() << "  " << c2.get_sum() << endl;
*/

Calculator ca1,ca2;
cin >> ca1 >> ca2;
//cout << ca1 << " + " << ca2 <<" = "<<ca1+ca2<< endl;

auto ca3 = ca1 / ca2;
cout << ca3.get_string() <<" = "<< ca3.get_sum(ca3.get_string())<<endl;

auto ca4 = ca1 * ca2;
cout << ca4.get_string() << " = " << ca4.get_sum(ca4.get_string()) << endl;

cout << sum("(1-(2*(3+2*2)))") << endl;

system("pause");
return 0;
}

``````

推荐阅读更多精彩内容

• 现在在太原，太原是山西省的省会城市，但一路走来并没有发现它过多的繁华，有高楼，有长街，却看不到想象中的热闹。在这下...
Harpo阅读 118评论 0 0
• 那些日子我近乎疯狂地祈祷他快点死掉，如果他不死掉那我就要死了。 不知是不是因为我的祈祷，他越来越虚弱越来越虚弱，我...
0088da845db6阅读 364评论 0 1
• 如果把身体比做一部工艺精巧，构造特殊的机器，最近不知道怎么了，无论如何也打理不好了。 还记得在22岁以前，这...
蓝雪夜阅读 105评论 0 0