您的位置:首页 > 编程语言 > C语言/C++

计算器之C++简易实现

2016-11-24 13:05 555 查看
利用完成算术表达式求值:
从键盘或文件中输入算术表达式,计算其结果并显示。
(1)转换为后缀表达式并输出;

(2)对后缀表达式求值并输出。

输入的表达式中可以有整数、实数、括号,运算符包括+、-、*、/、#(代表单目负)。可以多次输入不同的表达式进行计算,直到用户选择“退出”。

对于以上该计算器,我们可以先使用一个栈暂时存储操作符,最后用一个数组来保存后缀表达式;之后根据后缀表达式利用栈计算即可得到最终的答案。OK,上代码:

/**
* p_calc.h: 类的设计主要为内部接口函数的声明
*/

#ifndef _P_CALC_H_
#define _P_CALC_H_

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <cctype> //isdigit()
#include <cstdlib> //atof()

using namespace std;

class Calc
{
public:
Calc (string s_opers) : opers(s_opers) {}

// 用来判断后缀表达式是否能够成功转化
bool to_postfixExpression ();

// 计算
double pCalc();
double pCalc(double left, double right, char optr);

// 判断是否是操作符:'+'、'-'、'*'、'/'
bool isp_Optr(char c);

// 优先级判断
bool isp_notLow(char a, char b);

private:
string opers;
vector<string> pev;
};

#endif // _P_CALC_H_


/**
* p_calc.cpp: 头文件中的接口的实现
*/

#include "p_calc.h"

//////////////////////////////////////转化为后缀表达式
bool Calc::to_postfixExpression ()
{
///////////前期判断
char tc = opers[0];
if (!isdigit(tc) && tc != '#' && tc != '(' )
return false;

string st = "";
stack <char> pes;

int i = 0, j = 0, length = opers.length();

while (i < length)
{
if (isdigit(opers[i]))
{
j = i;
while (i++ < length && isdigit(opers[i] )) {}

if(i < length && opers[i] == '.')
{
if (!isdigit(opers[i+1]))
return false;
while (i++ < length && isdigit(opers[i])) {}
}

pev.push_back(opers.substr(j, i-j));

//cout << "数字子串:" << opers.substr(j, i-j) << "  j is: " << j << " i is: " << i << endl;
}

else if (isp_Optr(opers[i]))
{
if (isp_Optr(opers[i+1]) || opers[i+1] == '.')
return false;

if (!pes.empty() && pes.top() == '#')
{
pev.push_back("#");
pes.pop();
}

while (!pes.empty() && (isp_notLow(pes.top(), opers[i])))
{
pev.push_back(st+pes.top());
pes.pop();
}
pes.push(opers[i++]);
}

else if (opers[i] == '(')
{
if (isp_Optr(opers[i+1]))
return false;
pes.push(opers[i++]);
//cout << "i is: " << i << " ";
}

else if (opers[i] == ')')
{
while (pes.top() != '(')
{
pev.push_back(st+pes.top());
pes.pop();
}
pes.pop();
i++;
//cout << "i is: " << i << " ";
}

else if (opers[i] == '#')
{
if (isp_Optr(opers[i+1]))
return false;

pes.push(opers[i++]);
}
}

while (!pes.empty())
{
pev.push_back(st+pes.top());
pes.pop();
}
vector<string> :: iterator it;

cout << endl;
for (it = pev.begin(); it != pev.end(); it++)
cout << *it << " ";
cout << endl << endl;

return true;
}

////////////////////////////////////利用后缀表达式来计算值
double Calc::pCalc()
{
stack<double> pcalcs;

for (vector<string> :: iterator it = pev.begin(); it != pev.end(); it++)
{
if (isdigit((*it)[0]))
pcalcs.push( atof( (*it).c_str() ) );
else if (isp_Optr((*it)[0]))
{
double right = pcalcs.top(); pcalcs.pop();
double left = pcalcs.top();  pcalcs.pop();
pcalcs.push( pCalc( left, right, (*it)[0] ) );
}
else if ( *it == "#" )
{
double dt = pcalcs.top(); pcalcs.pop();
pcalcs.push(-dt);
}
}

double final_answer = pcalcs.top(); pcalcs.pop();

if (pcalcs.empty())
return final_answer;
else
return 0;

}

double Calc::pCalc(double left, double right, char optr)
{
double answer;

switch (optr) {
case '+': answer = left + right; break;
case '-': answer = left - right; break;
case '*': answer = left * right; break;
case '/': answer = left / right; break;
//case '%': (int)answer = (int)left % (int)right; break;
}

return answer;
}

bool Calc::isp_Optr(char c)
{
return (c == '+' || c == '-' || c == '*' || c == '/'); // || c == '%');
}

bool Calc::isp_notLow(char a, char b)
{
if ( a == '(' || b == '(') return false;
if ((a == '+' || a == '-') && (b == '*' || b == '/' || b == '%'))
return false;
return true;
}


/**
* main.cpp: 测试程序
*/

#include <iostream>
#include "p_calc.h"

using namespace std;

int main()
{
//p_calc test
string oper;

cout << "please enter your string expression(Ctr-Z to quit): " << endl;
while (getline(cin, oper))
{
Calc calcOper(oper);

if (oper.length() == 0)
cout << "You inputed nothing" << endl;
else if (calcOper.to_postfixExpression())
cout << "Final answer is: " << calcOper.pCalc() << endl << endl;
else
cout << "Bad oper" << endl;

cout << "please enter your string expression(Ctr-Z to quit): " << endl;
}
return 0;
}


input :

1.2+3.4*(5.6-7.8)/0.9

output:

1.2 3.4 5.6 7.8 - * 0.9 / +

Final answer is: -7.11111

OK, 以上完 :)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: