计算器实现

//表达式的输入只支持+-*/(),以#作为表达式的结束标识 
//空虚函数带来的错误 undefined reference to `vtable for Expression’
//纯虚函数没有实现 error: invalid new-expression of abstract class type ‘UserdataActionI’,有纯虚函数不允许创造对象 
//还可以进一步优化,为了减少麻烦,将基类中的部分成员开放,实际应该闭合
// Circulate()函数作为递归调用函数,无法进入基类中 
//没有使用课上的先输左表达式和右表达式的方式,把这一步本身纳入到递归中 
//首次使用vector 
#define ResultType double
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*********************建立表达式二叉树************/ 
//定义表达式树
typedef int TreeElemType;
typedef struct TreeNode {
	TreeElemType data;//可以将运算符转化储存,通过分辨左右孩子指针分辨是否是叶子节点,记得初始化! 
	struct TreeNode* left;
	struct TreeNode* right;
}TreeNode;
//算符优先级比较表 
char CList[7][7] =
{
	{ '>','>','<','<','<','>','>' },
	{ '>','>','<','<','<','>','>' },
	{ '>','>','>','>','<','>','>' },
	{ '>','>','>','>','<','>','>' },
	{ '<','<','<','<','<','=',' ' },
	{ '>','>','>','>',' ','>','>' },
	{ '<','<','<','<','<',' ','=' },
};//等号处理 
string Op = "+-*/()#";//方便用数组
bool In(char ch){
int i=0;
while(ch!=Op[i])
{i++;if(i>=7) break;}
return i<7; 
}
void CreateExpTree(TreeNode* &T, TreeNode* left, TreeNode* right, TreeElemType data)//建立叶子节点 
{
	T = new TreeNode;
	T->data = data;
	T->left = left;
	T->right = right;
}
//将数值型字符串转换成int型数字
int Atoi(string str)
{
int res = 0;
for(int i=0;i<str.size();i++)
res = res * 10 + (str[i]-'0');
return res;
}
//判断算符优先级
char Precede(char c1, char c2)
{
int i = 0, j = 0;
while (Op[i] && Op[i] != c1)
i++;
while (Op[j] && Op[j] != c2)
j++;
return CList[i][j];//i行j列 
}
//表达式树的创建算法
TreeNode* InitExpTree()
{
vector<TreeNode*> eTStackNode;//树栈 
vector<char> chStackNode;//算符栈
chStackNode.push_back('#');
char ch;
cin>>ch;
while(ch!='#'||chStackNode.back()!='#')//取反为退出条件 
{
if(!In(ch))//输入的是数字 
{
string num="";//定义在内部,每轮更新 
num+=ch; cin>>ch;
while(!In(ch)){
num+=ch; cin>>ch;
} //最后输入的是符号,注意程序的进行
TreeNode* T;
CreateExpTree(T,NULL,NULL,Atoi(num));//NULL,NULL叶子节点 
eTStackNode.push_back(T);
}
else{
TreeNode* temp1;
TreeNode* temp2;
TreeNode* T;
char temp_char;
switch(Precede(chStackNode.back(),ch)){
case '<':
chStackNode.push_back(ch); 
cin>>ch;
break;
 
case '>':
if(ch==')') 
{
while(chStackNode.back()!='('){
temp_char=chStackNode.back();chStackNode.pop_back();
temp1=eTStackNode.back();eTStackNode.pop_back();
temp2=eTStackNode.back();eTStackNode.pop_back();
CreateExpTree(T,temp2,temp1,temp_char);
eTStackNode.push_back(T);
}
chStackNode.pop_back(); 
cin>>ch;
break;
}
else
{
temp_char=chStackNode.back();chStackNode.pop_back();
temp1=eTStackNode.back();eTStackNode.pop_back();
temp2=eTStackNode.back();eTStackNode.pop_back();
CreateExpTree(T,temp2,temp1,temp_char);
eTStackNode.push_back(T);
break;
}
case '=':
chStackNode.push_back(ch);
cin>>ch;
break;
}
}
}
return eTStackNode.back();
}
/********************计算器相关类*********************/ 
class Expression{
//private:
public:
TreeNode* expression;
TreeNode* lchild;
TreeNode* rchild;
TreeElemType data;
public:
virtual ResultType value(){};//返回double类型结果//虚函数 
Expression();
Expression(TreeNode* T);
void Destory(TreeNode* T);
virtual ~Expression();
const TreeNode* get_expression(){return expression;};
const TreeNode* get_lchild(){return lchild;};
const TreeNode* get_rchild(){return rchild;};
const TreeElemType get_data(){return data;};
}; 
Expression::Expression(){
expression=NULL;
lchild=NULL;
rchild=NULL;
}
Expression::Expression(TreeNode* T){
expression=InitExpTree();
lchild=expression->left;
rchild=expression->right;
}
Expression::~Expression(){
// cout<<"析构函数调用"<<endl;
Destory(expression);//可以在析构函数内递归 
}
void Expression::Destory(TreeNode* T){//释放表达式树 
if(!T->left&&!T->right) delete T;
if(!T) return;//防止发生错误,访问NULL的孩子 
Destory(T->left);
Destory(T->right);
}
ResultType Circulate(const TreeNode* T);
class Add:public Expression{
public:
virtual ~Add(){;};
virtual ResultType value();
};
ResultType Add::value(){
if(!lchild&&!rchild) return data;
else return Circulate(lchild)+Circulate(rchild);
}
class Subtraction:public Expression{
public:
virtual ~Subtraction(){;};
virtual ResultType value();
};
ResultType Subtraction::value(){ 
if(!lchild&&!rchild) return data;
else return Circulate(lchild)-Circulate(rchild);
}
class Multiply:public Expression{
public:
virtual ~Multiply(){;};
virtual ResultType value();
};
ResultType Multiply::value(){ 
if(!lchild&&!rchild) return data;
else return Circulate(lchild)*Circulate(rchild);
}
class Divide:public Expression{
public:
virtual ~Divide(){;};
virtual ResultType value();
};
ResultType Divide::value(){ 
if(!lchild&&!rchild) return data;
else return Circulate(lchild)/Circulate(rchild);
}
ResultType Circulate(const TreeNode* T){
 
char flag= T->data;
if(In(flag))
switch(flag){//’char’是否能与int自动匹配!! 
case '+':{//用int储存运算符是为了叶子节点的兼容性,想用对应的Add对象等代替运算符,但在递归中无法处理叶子节点 
Expression *p=new Add;
p->lchild=T->left;
p->rchild=T->right;
return p->value();
}
case '-':{
Expression *p=new Subtraction;
p->lchild=T->left;
p->rchild=T->right;
return p->value();
}
case '*':{
Expression *p=new Multiply;
p->lchild=T->left;
p->rchild=T->right;
return p->value();
}
case '/':{
Expression *p=new Divide;
p->lchild=T->left;
p->rchild=T->right;
return p->value();
}
}
else return T->data;
}
/*void InOrderTree(TreeNode* T)
{
if (T)
{
InOrderTree(T->left);
if (T->left)
{
char ch = T->data;
cout << ch;
}
else
cout << T->data;
InOrderTree(T->right);
}
}*/
//表达式树的遍历 
int main(void){
TreeNode* T=NULL;
Expression cinin(T);//T只是为提供不同构造函数的标志性参数 
// InOrderTree(cinin.expression);
if(!cinin.get_lchild()&&!cinin.get_rchild()) cout<<cinin.get_data()<<endl;
else cout<<Circulate(cinin.get_expression())<<endl;
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值