问题描述
原问题如下:(From chapter 3, Additional exercises 10)
Programming Project:
I am sorry I can't find where the project is ! I just hear it from one of my classmate
Enter a string of expression ,you must consturct a tree devide from the string
and calculate the value of this expression
Back to Top
问题分析
1:输入一个表达式的字符串流从中识别出各种算术元素 如“+” “ –” 变量 和 整数浮点数。
2:用递归方法构建表达式树
3:树的数值运算找出未知变量,获得它的值,用后序遍历计算值
Back to Top

按钮说明
Enter : 将编辑框内的表达式读入程序,生成表达式树
Postorder: 后序遍历
Inorder: 中序遍历
Preorder 前序遍历
Insert Space : 决定生成的遍历式中是否插入空格,因为变量可能为多字符。
Calculation : 计算表达式值
操作过程
1:编辑器中输入一个表达式
2:按 Enter 键
3:此时表达式处理已经完成,如果表达式正确会有树生成,但未展开
4: 点击根部,浏览整棵树
5:按 Preorder ,Inorder 或Posorder 浏览三种遍历的结果
6:点击 Calculation 开始表达式数值的计算
7:程序遇到未知变量会弹出对话框
8:变量值输入后,程序会自动记录下,下次运算会自动调用
9:如果想要改动变量列表中变量的值,用鼠标在该变量上双击
程序结构
核心数据结构如下:
typedef struct Tree_Struct
{
CString Node;
Tree_Struct* left;
Tree_Struct* right;
}TreeStruct;
BOOL ConstructTree(TreeStruct *Leaf,CString Expression)
double Calculate(TreeStruct *Leaf)
CString Preorder(TreeStruct* Leaf)
CString Postorder(TreeStruct* Leaf)
CString Inorder(TreeStruct* Leaf)
BOOL TestWholeExpression(CString str)
BOOL CTreeDlg::ConstructTree(TreeStruct *Leaf, CString Expression)
//树的构建函数 , Leaf 是表达式树当前的工作节点 Expression 字符串流
CString str;
int length; //Expression 的长度
CString rightExpression; //截取下的右边子串
CString leftExpression; //截取下的左边子串
TreeStruct* RightLeaf; //右子树节点
TreeStruct* LeftLeaf; //左子树节点
length=Expression.GetLength();
if (length==0) return false; //如果字符串长度为零 认为输入非法
//这种设定是为防止 “ a + b - ” 这种情况
int Operator; //获得可作为节点的符号的位置
//返回规则演示
/*
(a+b)* (c+d) Operator=3
a+(b-d) Operator=2
a Operator=-1;
(a+b) Operator=-1;
*/
if (!TestWholeExpression(Expression)) return false; //判断表达式中括号是否匹配
//如果为 “(a+b) “ 类型去括号, 防止无限递归或作为一个变量
if (Expression[length-1]==')')
{
left=FindLeft(Expression,length-1);
//FindLeft() 是一个核心函数 返回与当前右括号匹配的右括号
if (left==-1) return false;
if (left==0) //说明为 “(a+b)” 类型
Expression=Expression.Mid(1,length-2);
length=Expression.GetLength();
if (length==0) return false;
}
//Find '+' Operator
Operator=Find(Expression,'+');
/*Find()是另外的一个重要函数 ,返回要找的字符最靠左边的位置
但是遇到括号要跳过
如果找不到返回 –1
如果发现表达式有语法错误返回 –2 */
if (Operator==-2) return false; //表达式有错误返回 false
if (Operator!=-1)
{
//确定左右子表达式
Cstring temp;
leftExpression.Format(Lefting(temp,Operator));
rightExpression.Format(Righting(temp,length-Operator-1));
//构建树
Leaf->Node="+";
RightLeaf=new TreeStruct;
LeftLeaf=new TreeStruct;
Leaf->left=LeftLeaf;
Leaf->right=RightLeaf;
if (!ConstructTree(RightLeaf,rightExpression)) return false;
if (!ConstructTree(LeftLeaf,leftExpression)) return false;
return true;
}
//Find "-" operator
.................................
//Find "*" operator
......................................
//Find "/" operator
.....................................
//不允许 “a()b” 这种变量的出现
if (FindChar(Expression,'(')!=-1) return false;
if (FindChar(Expression,')')!=-1) return false;
//确定叶节点
Leaf->Node=Expression;
Leaf->right=NULL;
Leaf->left=NULL;
return true;
}
//表达式的数值计算
double CTreeDlg::Calculate(TreeStruct *Leaf)
CDataDlg da;
//m_Error 是全局变量记录返回错误类型,与错误列表关连
if (IsOperator(Leaf->Node)) //IsOperator() 判断此节点是否是操作符
{
double dl=Calculate(Leaf->left);
if (m_Error) return 0;
double dr=Calculate(Leaf->right);
if (m_Error) return 0;
return Operation(Leaf->Node,dl,dr);
}
else
{
int index=FindInVariableList(Leaf->Node); //在变量栈中查找
if (index!=-1)
return m_Variable[index].data;
else
{
VariableSp++; //变量栈顶指针上移
m_Variable[VariableSp].variable=Leaf->Node;
m_Variable[VariableSp].data=(double)(atof(Leaf->Node));
if (m_Variable[VariableSp].data==0 &&
m_Variable[VariableSp].variable!="0")
{
da.m_Title.Format("Variable %s",Leaf->Node);
da.m_Data=0;
if (da.DoModal()==IDOK)
{
m_Variable[VariableSp].data=da.m_Data;
m_List.InsertItem(VariableSp,m_Variable[VariableSp].variable,1);
CString temp;
//itoa(da.m_Data,temp.GetBuffer(100),10);
_ultoa(da.m_Data,temp.GetBuffer(100),10);
m_List.SetItemText(VariableSp,1,temp);
}
}
return da.m_Data;
}
}
return -1;
}
CString CTreeDlg::Preorder(TreeStruct* Leaf)
//前序遍历
CString ss="";
if (Leaf==NULL) return ss;
ss=ss+Leaf->Node;
if (m_bInsertSpace) ss+=' ';
if (Leaf->left!=NULL)
ss+=Preorder(Leaf->left);
if (Leaf->right!=NULL)
ss+=Preorder(Leaf->right);
return ss;
}
CString CTreeDlg::Postorder(TreeStruct *Leaf)
//后序遍历
CString ss="";
if (Leaf==NULL) return ss;
if (Leaf->left!=NULL)
ss+=Postorder(Leaf->left);
if (Leaf->right!=NULL)
ss+=Postorder(Leaf->right);
ss=ss+Leaf->Node;
if (m_bInsertSpace) ss+=' ';
return ss;
}
CString CTreeDlg::Inorder(TreeStruct *Leaf)
//中序遍历
CString ss="";
if (Leaf==NULL) return ss;
if (Leaf->left!=NULL)
ss+=Inorder(Leaf->left);
if (Leaf->left && m_bInsertSpace) ss+=' ';
ss=ss+Leaf->Node;
if (Leaf->right && m_bInsertSpace) ss+=' ';
if (Leaf->right!=NULL)
ss+=Inorder(Leaf->right);
return ss;
}
BOOL CTreeDlg::TestWholeExpression(CString str)
int length=str.GetLength();
int sp=0;
for (int i=0;i<length;i++)
{
if (str[i]=='(') sp++;
if (str[i]==')') sp--;
}
if (sp!=0) return false;
return true;
}
浙公网安备 33010602011771号