首先我用string来储存数字,使得支持大数,并且将负数以最高位添加0来表示(会增加判断数字正负的困难,如:0.1是正数,00.1才是负数),并且自己编写了string数字的运算,有加减乘除、取模、开根号、幂运算、正余弦、e^x、阶乘,并且支持多重括号改变运算优先级。git仓库:https://git.oschina.net/light8lee/calculator.git,欢迎指教。
1.[代码]最简单的正则处理部分
string expression(str);
string pattern = "(\\()([-])([0-9]+)([.][0-9]+)?(\\))"; //find(-15)or(-15.02),and transform it into -15 or -15.02
regex r(pattern);
string format = "0$3$4";
expression = regex_replace(expression, r, format);
//cout << expression << endl;
pattern = "(\\()([0-9]+)([.][0-9]+)?(\\))"; //find(15)or(15.02),and transform it to 15 or 15.02
r.assign(pattern);
format = "$2$3";
expression = regex_replace(expression, r, format);
//cout << expression << endl;
pattern = "(s)([0-9]+)([.][0-9]+)?"; //find s(x), and calculate it as sin(x)
r.assign(pattern);
while (regex_search(expression, result, r))
{
temp = result.str(2) + result.str(3);
product = sin(temp);
expression = result.prefix().str() + product + result.suffix().str();
}
pattern = "(c)([0-9]+)([.][0-9]+)?"; //find c(x), and calculate it as cos(x)
r.assign(pattern);
while (regex_search(expression, result, r))
{
temp = result.str(2) + result.str(3);
product = cos(temp);
expression = result.prefix().str() + product + result.suffix().str();
}
pattern = "(e)([0-9]+)([.][0-9]+)?"; //find e(x), and calculate it as Exp(x)
r.assign(pattern);
while (regex_search(expression, result, r))
{
temp = result.str(2) + result.str(3);
product = Exp(temp);
expression = result.prefix().str() + product + result.suffix().str();
}
pattern = "([0-9]+)([.][0-9]+)?(!)"; //find (x)!, and calculate it as factorial(x)
r.assign(pattern);
while (regex_search(expression, result, r))
{
if (result.str(2) != "")
{
cerr << "invalid expression of " << result.str() << "!";
exit(1);
}
temp = result.str(1);
product = factorial(temp);
expression = result.prefix().str() + product + result.suffix().str();
}
pattern = "(\\()([0-9]+)([.][0-9]+)?([-+/*%#^]([0-9]+)([.][0-9]+)?)+(\\))"; //find the compound expression in the ( )
r.assign(pattern);
while (regex_search(expression, result, r))//inside start