利用二叉树实现表达式计算

// 本文利用二叉树实现简单的加减乘除的表达式运算:
//调用代码:
ExpressionTree ET = NULL;
   
 U8 in_str[]="(1+(33*4))+(((4*5)+9)*7)";
 ExpressionElementType exp_str[100]={0};
 U32 count = ConvertExpressionString(in_str,strlen(in_str),exp_str);
 ET = ExpressionTree_MakeTree(ET,exp_str,count);
 U32 result =  ExpressionTree_Calculate(ET);

// (1+(33*4))+(((4*5)+9)*8)

U32 ConvertExpressionString(U8* in_str,U32 count,ExpressionElementType* out_str) {     U8* str = in_str;     bool digits_flag = false;     U8 digit_buf[10]={0};     U32 digit_len = 0;     U32 exp_count = 0;       for(U32 ix=0;ix<count;ix++,str++)     {           if(ExpressionTree_IsOperand(*str)||(*str=='\(')||(*str=='\)'))           {                if(digits_flag)                {                 *out_str = atoi(digit_buf);             out_str++;       exp_count++;       memset(digit_buf,0,sizeof(digit_buf));             digits_flag = false;             digit_len = 0;                }                *out_str = (ExpressionElementType)*str;          out_str++;      exp_count++;           }     else     {          digits_flag= true;          digit_buf[digit_len++] = *str;     }     }

   str--;    if(*str!='\)')    {          *out_str = atoi(digit_buf);          out_str++;    exp_count++;    }

   return exp_count; }

 
ExpressionTree.cpp:
//---------------------------------------------------------------------------


#pragma hdrstop

#include "ExpressionTree.h"

#include <stdio.h>

#include <alloc.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)
//加法
ExpressionElementType Additon(ExpressionElementType left,ExpressionElementType right)
{
	return (left+right);
}
//减法
ExpressionElementType Subtraction(ExpressionElementType left,ExpressionElementType right)
{
	return (left-right);
}
//乘法
ExpressionElementType Multiplication(ExpressionElementType left,ExpressionElementType right)
{
	return (left*right);
}
//除法
ExpressionElementType Division(ExpressionElementType left,ExpressionElementType right)
{
	if(right==0)
	{
	   return 0;
	}
	return (left/right);
}
//百分比
ExpressionElementType Percentage(ExpressionElementType left,ExpressionElementType right)
{
	return (left*100);
}
//倒数
ExpressionElementType Reciprocal(ExpressionElementType left,ExpressionElementType right)
{
	if(left==0)
	{
        return 0;
    }
	return (1/left);
}

//最小值
ExpressionElementType Min(ExpressionElementType left,ExpressionElementType right)
{
	if(left < right)
	{
		return left;
	}
	return right;
}

//最大值
ExpressionElementType Max(ExpressionElementType left,ExpressionElementType right)
{
	if(left < right)
	{
		return right;
	}
	return left;
}

//平均值
ExpressionElementType Average(ExpressionElementType left,ExpressionElementType right)
{
	return (left+right)/2;
}



static Expression_Math_Table expression_math_table[] = {
	{'+', Additon},
	{'-', Subtraction},
	{'*', Multiplication},
	{'/', Division},
	{'<', Average},
	{'%', Percentage},
	{'X', Reciprocal}
};

#define Math_Table_Len (sizeof(expression_math_table)/sizeof(expression_math_table[0]))


ExpressionTree ExpressionTree_MakeEmpty(ExpressionTree T)
{
	if(T!=NULL)
	{
	   ExpressionTree_MakeEmpty(T->Left);
	   ExpressionTree_MakeEmpty(T->Right);
	   free(T);
	   T=NULL;
	}
	return NULL;
}

ExpressionTree ExpressionTree_Insert(ExpressionElementType X,ExpressionTree T)
{
	if(T==NULL)
	{
		T = (ExpressionTree)malloc( sizeof(ExpressionTreeNode));
		if(T==NULL)
		{
			printf("Out of memory\n");
		}
		else
		{
			T->E = X;
			T->Left = T->Right = NULL;
        }
	}
	else
	{
		if (T->Left==NULL)
		{
			T->Left = ExpressionTree_Insert(X,T->Left);
		}
		else if (T->Right==NULL)
		{
			T->Right = ExpressionTree_Insert(X,T->Right);
		}
		else
		{
		     printf("Has no empty child now.0x%X\n",T);
		}
	}
    return T;
}
//Go through the tree
ExpressionTree ExpressionTree_Traversal(ExpressionTree T)
{
      
}

bool ExpressionTree_IsOperand(ExpressionElementType X)
{
	  for(U32 ix=0;ix<Math_Table_Len;ix++)
	  {
		  if(expression_math_table[ix].Operand == X )
		  {
	              return true;
	          }
	   }
	   return false;
}

//(a+(b*c))+(((d*e)+f)*g)
/* Binary Tree Node Graph
				 +
				/ \
			  /	   \
			/		\
		   /         \
		 /            \
		/              \
	 +                  *
	/ \                 /  \
   a   *               +    g
	  / \             /  \
	 b  c            *    f
					/  \
				   d    e
*/

//Translate a string into expression tree.
//Assume that the string is valid for parsing.
//You should preprocess your string first to meet this function.
ExpressionTree ExpressionTree_MakeTree(ExpressionTree T,ExpressionElementType* Str,U32 Len)
{ 
   ExpressionElementType* str = Str;

   if(Len==0)
   {
      return T;
   }
   if(Len==1)
   {
      T = ExpressionTree_Insert (*str,T);
	return T;
   }
   
   if(Len==3) //A Operand B
   {
      T = ExpressionTree_Insert (*(str+1),T);//Current Node
      T = ExpressionTree_Insert (*(str),T);//Left
      T = ExpressionTree_Insert (*(str+2),T);//Right
      return T;
   }
   
   ExpressionElementType  left_parenthesis = '(';
   ExpressionElementType  right_parenthesis = ')';
   U32 count_left_parenthesis = 0;
   U32 count_right_parenthesis = 0;
   ExpressionElementType ch = 0;
   
   for(U32 ix=0;ix<Len;ix++,str++)
   {
       ch = *str;
	if(left_parenthesis==ch)
	{
	    count_left_parenthesis++;
	}
	if(right_parenthesis==ch)
	{
	    count_right_parenthesis++;
	}
	if ((count_left_parenthesis==count_right_parenthesis) && ExpressionTree_IsOperand(ch))
	{  //It is like "(a+(b*c))+(((d*e)+f)*g)"
	   //You searched "+" in the middle
         T = ExpressionTree_Insert (ch,T);//Current Node
	   if(*Str==left_parenthesis) //First is (
	   {
	      T->Left = ExpressionTree_MakeTree(T->Left,Str+1,ix-2);
	   }
	   else
	   {
		  T->Left= ExpressionTree_MakeTree(T->Left,Str,ix);
	   }
	   if (*(Str+ix+1)==left_parenthesis)
	   {
          	T->Right = ExpressionTree_MakeTree(T->Right,Str+ix+2,Len - ix -3); 
	   }
	   else
	   {
	      T->Right = ExpressionTree_MakeTree(T->Right,Str+ix+1,Len - ix -1); 
	   }
	}
   }

   return T;
	
}

ExpressionElementType ExpressionTree_Calculate(ExpressionTree T)
{
	ExpressionElementType result = (ExpressionElementType)0;

	if(T==NULL)
	{
		return (ExpressionElementType)0;
       }
	if((T->Left==NULL) && (T->Right==NULL)) //No Child,It's operator
	{
		result = T->E;
	}
	else  //Has child ,It's operand
	{
		  for(U32 ix=0;ix<Math_Table_Len;ix++)
		  {
			  if(expression_math_table[ix].Operand == T->E)
			  {
				  result = expression_math_table[ix].Fun(ExpressionTree_Calculate(T->Left),ExpressionTree_Calculate(T->Right));
				  break;
                      }
                }
       }
	return result;
}




ExpressionTree.h

//---------------------------------------------------------------------------

#ifndef ExpressionTreeH
#define ExpressionTreeH

#include "DataTypes.h"
//表达式的计算可以采用栈(数组实现)的结构来实现其计算结果功能

//(a+(b*c))+(((d*e)+f)*g)
/* Binary Tree Node Graph
				 +
				/ \
			  /	   \
			/		\
		   /         \
		 /            \
		/              \
	 +                  *
	/ \                 /  \
   a   *               +    g
	  / \             /  \
	 b  c            *    f
					/  \
				   d    e
*/
typedef struct ExpressionTreeNode *PtrToExpressionNode;
typedef struct ExpressionTreeNode *ExpressionTree;
typedef unsigned int ExpressionElementType;

struct ExpressionTreeNode
{
	ExpressionElementType E;
	ExpressionTree Left;
	ExpressionTree Right;
};

typedef ExpressionElementType (*Expression_FunPTr)(ExpressionElementType left,ExpressionElementType right);

typedef struct _Expression_Math_Table
{
	ExpressionElementType Operand;
	Expression_FunPTr Fun;
} Expression_Math_Table;


ExpressionTree ExpressionTree_MakeTree(ExpressionTree T,ExpressionElementType* Str,U32 Len);
ExpressionElementType ExpressionTree_Calculate(ExpressionTree T);
bool ExpressionTree_IsOperand(ExpressionElementType X);
ExpressionTree ExpressionTree_MakeEmpty(ExpressionTree T);


//---------------------------------------------------------------------------
#endif


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值