⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.cpp

📁 本程序实现的是以树型方式存储的表达式的各种操作
💻 CPP
字号:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "expression.h"
//摧毁表达式函数
void DestroyExpr(BiTree &E )
{
	if( E )
	{
		DestroyExpr( E->lchild );
		DestroyExpr( E->rchild );
		free(E);
	}
	E = NULL;
}
//输入表达式函数
int ReadExpr(BiTree &T)
{
	if( !T )
		DestroyExpr(T);
	char e;
	e=getchar();	     
	if(e=='+'||e=='-'||e=='*'||e=='/'||e=='^')   //如果输入的是符号,则进行递归调用
	{
		T=(BiTree)malloc(sizeof(LNode));
		(T->data).oper=e;
		T->tag=0;
		if(!ReadExpr(T->lchild)) return 0;    //先进行左子树的递归操作
		if(!ReadExpr(T->rchild)) return 0;    //再进行右子树的递归操作
	}
	else
	{
		if(e>='0'&&e<='9'||e>='a'&&e<='z')    //如果输入的变量合法,则给树叶节点赋值
		{
			T=(BiTree)malloc(sizeof(LNode));
			T->lchild=NULL; T->rchild=NULL;
			if(e>='0'&&e<='9')
			{
				T->data.num=e-'0';
				T->tag=1;
			}
			else
			{
				(T->data).oper=e;
				T->tag=2;
			}
		}
		else                               //若输入的变量不合法则提示输入错误
			printf("输入错误\n");
	}
	return 1;
}
//操作符优先比较函数
int Compare(char a,char b)    
{
	if( ((a=='*' || a=='/') && (b=='+' || b=='-')) || a=='^' && b!='^')
		return 1;
	else
		return 0;
}
//表达式输出函数
int WriteExpr(BiTree T)
{
	if( !T )
		return 1;
	int p,q;
	if(T->tag == 0)
	{
		if( !T->lchild || !T->rchild )   //当树的左右孩子树均空时返回
			return 0;
		p = T->lchild->tag;
		if((p == 0)&&Compare(T->data.oper,T->lchild->data.oper))
		{
			printf("(");   //比较符号的优先关系,从而判断是否要进行添加括号的操作
			if(!WriteExpr(T->lchild)) return 1;
			printf(")");
		}
		else if( !WriteExpr( T->lchild) )   //如不需要添加括号则直接进行递归调用
			return 0;
		printf("%c",(T->data).oper);
        q = T->rchild->tag;  //右子树也进行如上的操作
		if((q == 0)&&Compare(T->data.oper,T->rchild->data.oper))
		{ 
			printf("(");
			if( !WriteExpr( T->rchild) ) return 0;
			printf(")");
		}  
		else if( !WriteExpr( T->rchild) ) 
			return 0;
	}
	else    //当调用到叶子节点时进行如下操作
	{
		if(T->tag==1)
		{
			if(T->data.num<0)
			{
				printf("(");
				printf("%d",T->data.num);
				printf(")");
			}
			else
				printf("%d",T->data.num);
		}
		else
			printf("%c",(T->data).oper);
	}
	return 1;
}
//变量赋值函数
int Assign(BiTree &T,char V,int c)
{
	if(T->tag==0)
	{
		if(!Assign(T->lchild,V,c)) return 1;   //递归调用查找叶子节点
		if(!Assign(T->rchild,V,c)) return 1;
	}
	else       //当找到叶子节点后进行变量的赋值操作
		if(T->tag==2 && T->data.oper==V)
		{
			T->data.num=c;
			T->tag=1;
		}
	return 1;
}
//表达式求值函数
int Value(BiTree &T)
{
	char oper;
	int i;
	int a,b,sum;
	if(T->tag == 0)
	{
		oper=T->data.oper;
		a=Value(T->lchild);   //递归调用求值函数在求树T的左右孩子树的值
		b=Value(T->rchild);
	}
	else
		return T->data.num;
	switch(oper)    //根据运算符进行相应的运算操作
	{
		case '+':return(a+b);
		case '-':return(a-b);
		case '*':return(a*b);
		case '/':return(a/b);
		case '^':sum=a;
				 for(i=1;i<b;++i)
					 sum*=a;
				 return(sum);
	}
	return 0;
}
//构造复合表达式函数
BiTree CompoundExpr(char p,BiTree E1,BiTree E2)
{
	BiTree E;
	E=(BiTree)malloc(sizeof(LNode));
	E->lchild=E1;          //将E的左孩子设为E1,右孩子设为E2
	E->rchild=E2;
	E->data.oper=p;
	E->tag = 0;
	return E;
}
//合并常数项的函数
int MergeConst(BiTree &T)
{
	BiTree p,q;
	if( T->lchild->tag == 0 )   //若左子树的数据为操作符,则递归调用合并函数
		MergeConst(T->lchild);
	if( T->rchild->tag == 0 )   //若右子树的数据为操作符,则递归调用合并函数
		MergeConst(T->rchild);
	if( T->lchild->tag == 1 && T->rchild->tag == 1 )  //若左右孩子均为数字,则进行合并操作
	{
		p=T->lchild;
		q=T->rchild;
		T->data.num = Value(T);
		T->tag = 1;   //将该节点标记为数字节点
		free(p);   //释放无用的子节点
		free(q);
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -