#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
#include <cmath>
using namespace std;
typedef string::iterator Iter;
void basicFour(string &); // 用于基础四则运算
void abord(string &); // 用于处理括号
void insertBrackets(string &); // 用于插入括号
inline double& toDouble(const string &);
int main(){
string input;
cin >> input;
try{
abord(input);
}catch(runtime_error e){
cout << e.what() << endl;
system("pause");
return 1;
}
cout << input << endl;
system("pause");
return 0;
}
void basicFour(string &str){
if (str[0] == '-')
str.insert(0, "0");
int d = 0;
for (string::size_type i = 0; i < str.size() - 1; ++i)
if (!isdigit(str[i]) && !isdigit(str[i + 1]))
++d;
int count = 0;
for (Iter i = str.begin(); i != str.end(); ++i)
if (*i == '+' || *i == '-' || *i == '*' || *i == '/')
++count;
count -= d;
double *num = new double [count + 1]();
char *oper = new char [count];
istringstream change(str);
for (int i = 0, j = 0, k = 0; j < count + 1; ++i){
if (!(i % 2))
change >> num[j++];
else
change >> oper[k++];
}
for (size_t i = 0; i < count; ++i){
if ((i + 1) < count && (oper[i] == '+' || oper[i] == '-') && (oper[i + 1] == '*' || oper[i + 1] == '/')){
switch (oper[i + 1]){
case '*':
num [i + 2] *= num[i + 1]; break;
case '/':
if (num[i + 2] == 0)
throw runtime_error("错误,0做分母");
else
num[i + 2] = num[i + 1] / num[i + 2]; break;
}
switch (oper[i]){
case '+':
num[i + 2] += num[i]; break;
case '-':
num[i + 2] = num[i] - num[i + 2]; break;
}
++i;
}else{
switch(oper[i]){
case '+':
num [i + 1] += num[i]; break;
case '-':
num[i + 1] = num[i] - num[i + 1]; break;
case '*':
num[i + 1] *= num[i]; break;
case '/':
if (num[i + 1] == 0)
throw runtime_error("错误,0做分母");
else
num[i + 1] = num[i] / num[i + 1]; break;
}
}
}
ostringstream os;
os << num[count];
str = os.str();
delete [] num, oper;
}
void abord(string &str){
insertBrackets(str);
if (str.find("(") != string::npos){
int flag_1 = str.find_last_of("(") + 1;
for (Iter i = str.begin() + flag_1; i < str.end(); ++i){
if (*i == ')'){
int flag_2 = i - str.begin();
string& calc = str.substr(flag_1, flag_2 - flag_1);
basicFour(calc);
double c = 0;
c = toDouble(calc);
if (flag_1 - 4 >= 0){
switch(str[flag_1 - 4]){
case 's':
c = sin(c);
flag_1 -= 4;
goto a;
case 'c':
c = cos(c);
flag_1 -= 4;
goto a;
case 't':
c = tan(c);
flag_1 -= 4;
goto a;
case 'l':
c = log(c);
flag_1 -= 4;
goto a;
}
}
if (flag_1 - 2 >= 0 && str[flag_1 - 2] == '^'){
int count = 0;
string num;
if (str[flag_1 - 3] == ')'){
int p = 1;
for (int j = flag_1 - 4; j >= 0; --j){
if (str[j] == ')')
++p;
if (str[j] == '(')
--p;
if (p == 0){
count = j;
break;
}
}
num = str.substr(count + 1, flag_1 - 4 - count);
abord(num);
flag_1 = count;
}else{
for (int j = flag_1 - 3; j >= 0; --j){
if (isdigit(str[j]) || str[j] == '.')
++count;
else
break;
}
flag_1 -= (count + 2);
num = str.substr(flag_1, count);
}
c = pow(toDouble(num), c);
}else
--flag_1;
a:
calc.clear();
ostringstream os;
os << c <<flush;
calc = os.str();
str = str.substr(0, flag_1) + calc + str.substr(flag_2 + 1);
abord(str);
break;
}
if (i == str.end() - 1)
throw runtime_error("错误,括号不配对");
}
}else if (str.find(")") != string::npos)
throw runtime_error("错误,括号不配对");
else
basicFour(str);
}
void insertBrackets(string &str){
int count = 0;
for (int i = str.size(); i != 0; --i){
if (isdigit(str[i]) || str[i] == '.')
++count;
else if(count && (str[i] == 'n' || str[i] == 's' || str[i] == 'g' || str[i] == '^')){
str.insert(i + 1, "(");
str.insert(i + count + 2, ")");
}else if (count && str[i] == '-' && (str[i - 1] == 'n' || str[i - 1] == 's' || str[i - 1] == 'g' || str[i - 1] == '^')){
str.insert(i, "(");
str.insert(i-- + count + 2, ")");
}else
count = 0;
}
}
inline double& toDouble(const string &str){
istringstream is(str);
double r = 0;
is >> r;
return r;
}
一个基于控制台的简单计算器,实现了大部分计算操作,存着里存着,方便以后作业使用。