当前位置:文档之家› 数据结构课程设计—十进制四则运算计算器的设计与实现

数据结构课程设计—十进制四则运算计算器的设计与实现

十进制四则运算计算器的设计与实现1.问题描述(1)题目描述:在以二叉树表示算术表达式的基础上,设计一个十进制的四则运算计算器。

(2)基本要求:实现整数或浮点数的四则运算。

(3)测试数据:12 - ( - 4 ) * ( ( 20 + 3 / 5 ) * 8 / 5 ) * ( - 4 ) #=-515.36- ( 22.7 - 4208.3 ) / ( ( 2.4 + 1.6 ) * 12 ) + 4.4 - 2.9 #=88.710 - ( - 3 ) * ( ( 21 + 3 / 5 ) * 8 / 3 ) * ( - 2 ) #=-335.62.需求分析(1)程序实现的功能是从键盘输入有效的表达式,求出其值并输出(2)程序运行后,会提示用户输入表达式,并判断是否有效,并返回值3.概要设计为了实现程序功能,用二叉树存储表达式,然后从二叉树按后序遍历的方式取出数据,进行运算,运算时用堆栈存储数据。

(1)二叉链表的定义ADT BinaryTree{//数据对象D:D是具有相同特性的数据元素的集合。

//数据关系R:// 若D=Φ,则R=Φ,称BinaryTree为空二叉树;// 若D≠Φ,则R={H},H是如下二元关系;// (1)在D中存在惟一的称为根的数据元素root,它在关系H下无前驱;// (2)若D-{root}≠Φ,则存在D-{root}={D1,Dr},且D1∩Dr =Φ;// (3)若D1≠Φ,则D1中存在惟一的元素x1,<root,x1>∈H,且存在D1上的关系H1 ?H;若Dr≠Φ,则Dr中存在惟一的元素xr,<root,xr>∈H,且存在上的关系Hr ?H;H={<root,x1>,<root,xr>,H1,Hr};// (4)(D1,{H1})是一棵符合本定义的二叉树,称为根的左子树;(Dr,{Hr})是一棵符合本定义的二叉树,称为根的右子树。

//基本操作:InitBiTree( &T )//操作结果:构造空二叉树T。

DestroyBiTree( &T )// 初始条件:二叉树T已存在。

// 操作结果:销毁二叉树T。

CreateBiTree( &T, definition )// 初始条件:definition给出二叉树T的定义。

// 操作结果:按definiton构造二叉树T。

ClearBiTree( &T )// 初始条件:二叉树T存在。

// 操作结果:将二叉树T清为空树。

BiTreeEmpty( T )// 初始条件:二叉树T存在。

// 操作结果:若T为空二叉树,则返回TRUE,否则返回FALSE。

BiTreeDepth( T )// 初始条件:二叉树T存在。

// 操作结果:返回T的深度。

Root( T )// 初始条件:二叉树T存在。

// 操作结果:返回T的根。

Value( T, e )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:返回e的值。

Assign( T, &e, value )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:结点e赋值为value。

Parent( T, e )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:若e是T的非根结点,则返回它的双亲,否则返回“空”。

LeftChild( T, e )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:返回e的左孩子。

若e无左孩子,则返回“空”。

RightChild( T, e )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:返回e的右孩子。

若e无右孩子,则返回“空”。

LeftSibling( T, e )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:返回e的左兄弟。

若e是T的左孩子或无左兄弟,则返回“空”。

RightSibling( T, e )// 初始条件:二叉树T存在,e是T中某个结点。

// 操作结果:返回e的右兄弟。

若e是T的右孩子或无右兄弟,则返回“空”。

InsertChild( T, p, LR, c )// 初始条件:二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空。

// 操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树。

p所指结点的原有左或右子树则成为c的右子树。

DeleteChild( T, p, LR )// 初始条件:二叉树T存在,p指向T中某个结点,LR为0或1。

// 操作结果:根据LR为0或1,删除T中p所指结点的左或右子树。

PreOrderTraverse( T, visit() )// 初始条件:二叉树T存在,Visit是对结点操作的应用函数。

// 操作结果:先序遍历T,对每个结点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

InOrderTraverse( T, visit() )// 初始条件:二叉树T存在,Visit是对结点操作的应用函数。

// 操作结果:中序遍历T,对每个结点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

PostOrderTraverse( T, visit() )// 初始条件:二叉树T存在,Visit是对结点操作的应用函数。

// 操作结果:后序遍历T,对每个结点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

LevelOrderTraverse( T, visit() )// 初始条件:二叉树T存在,Visit是对结点操作的应用函数。

// 操作结果:层次遍历T,对每个结点调用函数Visit一次且仅一次。

一旦visit()失败,则操作失败。

(2)本程序包含的模块判断表达式主函数模块创建二叉树计算结果、输出4.详细设计(1)二叉树的二叉链表类型定义typedef struct BitNode{ElemType data;struct BitNode *Lchild,*Rchild;//二叉树的左右孩子和父母} BitNode;typedef BitNode *BitTree;(2)树的结构定义class binarytree//树的类{public:BinNode *root; //根节点binarytree(void){root=NULL;} //构造函数void print(void){print(root);}void print(BinNode *p){if(p!=NULL){print(p->left_child);print(p->right_child);cout<<p->data<<" ";}}void evaluate(void){evaluate(root);}bool evaluate(BinNode *prt) //计算二叉树一个节点{if(IsOperator(prt->data)&&!IsOperator(prt->left_child->data)&&!IsOperator(prt->right_chil d->data))//计算二叉树结点的值并存入新的二叉树结点{float num=0;float num1=atof(prt->left_child->data.c_str());float num2=atof(prt->right_child->data.c_str());if(prt->data=="+")num=num1+num2;else if(prt->data=="-")num=num1-num2;else if(prt->data=="*")num=num1*num2;else if(prt->data=="/"){if(num2==0.0){cout<<"除数为零运算出错";return 0;}elsenum=num1/num2;}else if(prt->data=="^")num=pow(num1,num2);else if(prt->data=="%"){if(num2==0.0){cout<<"除数为零运算出错";return 0;}elsenum=(long)num1%(long)num2;}stringstream bob;bob<<num;string suzzy(bob.str());prt->data=suzzy;prt->left_child=NULL;prt->right_child=NULL;}else if(prt->left_child==NULL&&prt->right_child==NULL);else{evaluate(prt->left_child);evaluate(prt->right_child);evaluate(prt);}return 1;}void clear_help(void){clear_help(root);}void clear_help(BinNode *rt){if(rt!=NULL){clear_help(rt->left_child);clear_help(rt->right_child);delete rt;}}}判断表达式是否正确bool judge(string exp) //判断输入是否正确{char check;int error=0,lb=0,rb=0,numofoperand=0,numofoperator=0;for(int m=0;m<exp.size();m++){check=exp[m];if(IsOperand(check)){if(check=='.')//判断浮点型数据是否正确{if(!(exp[m-1]>='0'&&exp[m-1]<='9')&&(exp[m+1]>='0'&&exp[m+1]<='9')){error++;cout<<"浮点型数据输入有误"<<endl;}}numofoperand++;}else if(IsOperator(check)){if(check==')'){rb++;if(rb>lb){error++;cout<<"右括号不可能大于左括号"<<endl;}if(IsOperator(exp[m+1])&&(exp[m+1]=='+'||exp[m+1]=='-'||exp[m+1]=='*'||exp[m+1]=='/'||e xp[m+1]==')')){numofoperator++;m++;if(exp[m]==')')rb++;}else if(IsOperator(exp[m+1])||IsOperand(exp[m+1])){error++;cout<<"右括号后不可能直接跟数据或左括号"<<endl;}}else if(check=='('){lb++;if(IsOperator(exp[m+1])&&exp[m+1]=='('||exp[m+1]=='-')//左括号右边只能是数字或者"-"号{m++;m++;lb++;}else if(IsOperator(exp[m+1])){error++;cout<<"左括号后运算符只能跟左括号"<<endl;}}else{numofoperator++;if(IsOperator(exp[m+1])&&exp[m+1]=='('){m++;lb++;}else if(IsOperator(exp[m+1])){error++;cout<<"非括号的运算符不能直接接非括号运算符"<<endl;}}}else{error++;cout<<check<<"为非法字符"<<endl;}}if((error==0)&&(lb==rb)&&(numofoperand!=0)&&(numofoperator!=0))return true;elsereturn false;}5.调试分析(1)程序将所有的二叉树的子树用binarytree进行创建子树,然后将子树的孩子结点和数据域进行计算,存入上一层树的孩子结点中,从而使算术比较节约时间。

相关主题