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

📄 change.cpp

📁 逻辑表达式转化
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "logic.h"



void Node::delNode( link rhs )
{
	if( rhs->left )
		delNode( rhs->left );
	if( rhs->right )
		delNode( rhs->right );
	delete rhs;
	rhs = NULL;
}

													///////////////////////////////////////////////

		//构造函数初始化成员变量
LogicTree::LogicTree():
		  tree( NULL ),
		  num( 0 ),
		  index_1( 0 ),
		  index_2( 0 ),
		  num1( 0 ),
		  goon( 0 )
{
    int i ;
	for(  i = 0 ; i<54 ; i++ )
		*(value+i) = *(value_1+i) = '\0';
	for(  i = 0 ; i<MAX ; i++ )
		*(string1+i) = *(string2+i) = *(string3+i) = NULL;
}

													///////////////////////////////////////////////

		//重载运算符
Node & Node::operator =( const Node & rhs )
{
    if( this == &rhs )				//如果赋给自已,则返回自身
		return *this;
    data      = rhs.data;
	bracket   = rhs.bracket;
	negate1   = rhs.negate1;
	isOperand = rhs.isOperand;
	character = rhs.character;
	return *this;
}

													///////////////////////////////////////////////
		


link LogicTree::copy( link _tree )
{
	if( _tree )						//如果参数不为空,则复制该结点
	{
		link theTree = new Node;
	    *theTree = *_tree;
		theTree->left = copy( _tree->left );
		theTree->right = copy( _tree->right );
		return theTree;	
	}
	else							//如果是空,则结束递归函数
		return NULL;
}

													///////////////////////////////////////////////


int LogicTree::isRight( char * rhs )
{
	int i = 0;
	int j = 0;
	int k = 0;

	if( *rhs == '\0' || *rhs == '\n' )
		return 0;
	for(; *(rhs+i) != '\0' && *(rhs+i) != '\n'; i++)
	{
		if( !isOperator( *(rhs+i) ) && !isCharacter( *(rhs+i) ) && !isLeftBracket( *(rhs+i) )\
			&& !isRightBracket( *(rhs+i) ) && *(rhs+i) != '!' )			//如果字符串中不合法的字符,返回0
			return 0;
		if( i )
		{
			if( isLeftBracket( *(rhs+i) ) )					//如果是左括号
			{
				j++;
				if( isRightBracket( *(rhs+i-1) ) || isCharacter( *(rhs+i-1) ) ) 
					return 0;								//前一个为操作数或右括号,返回0
			}
			else if( isRightBracket( *(rhs+i) ) )			//如果是右括号
			{
				j--;
				if( isLeftBracket( *(rhs+i-1) ) || isOperator( *(rhs+i-1) ) || *(rhs+i-1) == '!' )
					return 0;								//前一个为左括号、操作数或 ! ,返回0
			}
			else if( isCharacter( *(rhs+i) ) )				//如果是操作数
			{
				if( isCharacter( *(rhs+i-1) ) || isRightBracket( *(rhs+i-1) ) ) 
					return 0;								//如果前一个是操作或右括号,返回0
				for( k = 0 ; *(value+k) != '\0' && *(value+k) != *(rhs+i) ; k++ );
				if( *(value+k) == '\0' )					//如果该操作数不在数组是
				{
					num1 = k+1;
					*(value+k) = *(rhs+i);					//记录该操作数
				}
			}
			else if( *(rhs+i) == '!' )						//如果是 ! 
			{
				if( isRightBracket( *(rhs+i-1) ) || *(rhs+i+1) == '\0' )
					return 0;								//如果前一个是右括号或后一个为结束符,返回0
			}
			else					//为运算符
			{
				if( isLeftBracket( *(rhs+i-1) ) || isOperator( *(rhs+i-1) ) || \
					*(rhs+i-1) == '!' || *(rhs+i+1) == '\0' || *(rhs+i+1) == '\0' )
					return 0;
			}
		}
		else						//i = 0
		{
			if( isLeftBracket( *rhs ) )
				j++;
			else if( isRightBracket( *rhs ) || isOperator( *rhs ) )
				return 0;
			else if( isCharacter( *(rhs+i) ) )		//记录弟一个操作数
				*(value+(num1++)) = *rhs;
			else if( *(rhs+1) == '\0' )
				return 0;
		}
	}
    if( j )			//如果括号不对称
		return 0;
	return 1;
}

													///////////////////////////////////////////////


void LogicTree::delTree( link _tree )
{
	if( _tree )				//如果结点不为空则删除左右结点
	{
		delTree( _tree->left );
		delTree( _tree->right );	
	
	delete _tree;			//再删除头结点
	_tree = NULL;
	}
}

													///////////////////////////////////////////////

				//如果是操作数,则返回1,否则返回0
int LogicTree::isCharacter( char rhs )const
{
	if( ( rhs >= 97 && rhs <= 122 ) || ( rhs >= 65 && rhs <= 90 ) )
		return 1;
	return 0;
}

													///////////////////////////////////////////////


int LogicTree::isOperator( char rhs )const
{
	switch( rhs )
	{
	case '\\':
    case '/':
	case '>':return 1;			//如果是运算符,则返加1
	default:return 0;			//如果不是运算符,返回0
	}
}

													///////////////////////////////////////////////


void LogicTree::clean( link rhs )
{
	if( rhs )
	{
		if( isCharacter( rhs->character ) )
			for( int i = 0 ; *(value+i) != '\0' ; i++ )
				if( rhs->character == *(value+i) )
				{
					*(value_1+i) = '*';		//如果已存在该字符,则把该位设为 * 
					return;					//跳出本次函数
				}
	
		clean( rhs->left );					//刷新左结点
		clean( rhs->right );				//刷新右结点
	}
}

													///////////////////////////////////////////////

			//判断各个运算符的优先级
int LogicTree::priority( char rhs )const
{
	switch( rhs )
	{
	case '>':return 1;
	case '\\':return 2;
	case '/':return 3;	
	default:return 4;
	}
}

													///////////////////////////////////////////////

			
void LogicTree::print( link rhs )
{
	int yes_l = 0;			//判断是否打印左括号
	int yes_r = 0;			//判断是否打印右括号

	if( rhs )				//rhs不为空
	{
		if( isOperator( rhs->character ) )		//如果该结点为运算符,打印左子树
		{
			if( isOperator( rhs->left->character ) )
				if( rhs->character != rhs->left->character || rhs->left->bracket || rhs->left->negate1 )
					yes_l = 1;			//运算符外层有括号
		
			if( rhs->left->negate1 )
				cout<<"!";
			if( yes_l )					//有括号就打印括号
				cout<<"(";

			print( rhs->left );			//打印以该结点为头结点的子树
			
			if ( yes_l )				//如果打印了左括号就再打印右括号
				cout<<")";
		}

		if( rhs->character == '\\' )
			cout<<"\\/";
		else if( rhs->character == '/' )
			cout<<"/\\";
		else if( rhs->character == '>' )
			cout<<"->";
		else
			cout<<rhs->character;

		if( isOperator( rhs->character ) )		//打印右子树
		{
			if( isOperator( rhs->right->character ) )
				if( rhs->character != rhs->right->character || rhs->right->bracket || rhs->right->negate1 )
					yes_r = 1;
			
			if( rhs->right->negate1 )
				cout<<"!";
			if( yes_r )
				cout<<"(";	
			print( rhs->right );
			if( yes_r )
				cout<<")";
		}
	}
}

													///////////////////////////////////////////////


void LogicTree::printTree()
{
	int i = 0;
	cout<<"<=> ";
	if( tree->negate1 )			//如果顶结点有否定
	{
		cout<<"!";
		if( isOperator( tree->character ) )		//如果顶结点为运算符,在外层打印括号,否定直接打印
			i = 1;
		if( i )
			cout<<"(";
		print( tree );
		if( i )
			cout<<")";
	}
	else
		print( tree );			//如果顶结点没有否定,则直接打印
		cout<<endl;
}

													///////////////////////////////////////////////

			//头结点为合取,子结点中至少有一个为析取,进行计算
link LogicTree::changeNode_1( link rhs )
{
	link newnode = new Node('\\', false ,true );		//建立一个析取结点
	link newnode_1 = copy( rhs );					//产生一个子树的复本
	newnode->left = rhs;							//将原结点设为新结点的左结点
	newnode->right = newnode_1;						//将复本结点设为新结点的右结点
    link temp_1;									//记录临时子树
	link temp_2;

	if( rhs->left->character == '\\' )
	{
		temp_1 = rhs->left;
		temp_2 = newnode_1->left;
		rhs->left = copy( temp_1->left );
		newnode_1->left = copy( temp_2->right );
	}                                                              
	else
	{
		temp_1 = rhs->right;
		temp_2 = newnode_1->right;
		rhs->right = copy( temp_1->left );
		newnode_1->right = copy( temp_2->right );
	}
	delTree( temp_1 );
	delTree( temp_2 );

	return newnode;
}


void LogicTree::F5 ()
{
	int i = 0;
	int k = 0;				//设置是否跳出整个循环
	link node_1 = NULL;		//记录头结点
	link node_2 = NULL;		//记录头结点或它的前一结点
	link node_3 = NULL;		//记录头结点的后一结点

	for( ; i<index_2 ; i++ )
	{
		k = 0;
		node_2 = NULL;
		node_1 = *(string2+i);			//初始化node_1为简音合取式的头结点
		for( ; node_1 && node_1->isOperand ; node_2 = node_1,node_1 = node_1->left )
		{
			node_3 = node_1->left ;			//初始化与头结点相比较的结点
			while( node_1->left->isOperand )		
			{
				if( node_1->right->character > node_3->right->character )		//因为在前面已经为它排序
					break;
															//两个运算符相同
				if( node_1->right->negate1 == node_3->right->negate1 )			
				{														//若否定相同,则删去与头结点相比较的结点
					node_1->left = node_3->left;
					delete node_3->right;
					delete node_3;
				}
				else					//若否定不同,该简单合取范式恒为假,删去该简单合取范式
				{
					if( *(string2+i) == tree )
						tree = NULL;
					else
					{
						if( string3[i]->left == *(string2+i) )
							string3[i]->left = NULL;
						else
							string3[i]->right = NULL;
					}
					delTree( *(string2+i) );
					*(string2+i) = NULL;
					k = 1;
					break;			//跳出循环
				}		
				node_3 = node_1->left;
			}
			if( k )
				break;						//头结点的左结点为操作数
			if( node_1->left->character == node_1->right->character )	
				if( node_1->left->negate1 == node_1->right->negate1 )		//否定相同,删去头结点的右结点
				{				
					node_3 = node_1;
					if( node_2 )
					{														//当该简单合取式头结点的左结点为操作数
						node_2->left = node_1->left;
						node_1 = node_2->left;
					}
					else								//当该简单合取式头结点的左结点不为操作数
					{
						if( string3[i]->left == *(string2+i) )
							string3[i]->left = node_1->left;
						else
							string3[i]->right = node_1->left;

						*(string2+i) = node_1->left;
						node_1 = *(string2+i);
					}
					delete node_3->right;
					delete node_3;
				}
				else									//否定相同,删去该简单合取式
				{
					if( tree == *(string2+i) )			//若整个表达式只有一个简单合取式,要将tree设为NULL
						tree = NULL;
					else
					{
						if( string3[i]->left == *(string2+i) )
							string3[i]->left = NULL;
						else
							string3[i]->right = NULL;
					}
					delTree( *(string2+i) );
					*(string2+i) = NULL;
					break;			//跳出循环
				}
		}
	}
}


													///////////////////////////////////////////////

		//为方便输出,用选择排序阖对每个简单合取式排序。
void LogicTree::paiXu( int &k)
{
	int i = 0;
	link node_1 = NULL;		//记录对比结点的父结点
	link node_2 = NULL;		//记录当前最小结点的父结点
	link node_3 = NULL;		//记录要进行比较的结点的父结点
   
	for(; *(string2+i) != '\0' ; i++ )
	{
		for(node_1 = *(string2+i); node_1->isOperand ; node_1 = node_1->left )
		{
			node_2 = node_1;
			for( node_3 = node_1->left ; node_3->isOperand ; node_3 = node_3->left )
			{
				if( node_2->right->character < node_3->right->character && ++k )
					node_2 = node_3;				//当前最小结点大于进行比较的结点,重设当前最小结点
				if( !node_3->left->isOperand )		//若进行比较的结点为操作数,则与它进行比较
					if( node_2->right->character < node_3->left->character && ++k )
						node_2 = node_3;
			}		
			
			if( node_1 != node_2 )		//对比不是最小结点
			{
										//node_2的右结点为最小结点
				if( node_2->left->isOperand || ( !node_2->left->isOperand &&\
					node_2->left->character < node_2->right->character ) )
				{
					node_3 = node_1->right;
					node_1->right = node_2->right;
					node_2->right = node_3;
				} 
				else					//node_2的左结点为最小结点
				{
					node_3 = node_1->right;
					node_1->right = node_2->left;
					node_2->left = node_3;
				}
			}
			else if( node_2->left->character > node_2->right->character )
			{											//对比结点的左结点为操作数,且右结点大于左结点
				node_3 = node_2->left;
				node_2->left = node_2->right;
				node_2->right = node_3;
			}
		}
	}
}
													///////////////////////////////////////////////

		//建立新的二叉树来正职放排序好的简单合取式
link LogicTree::newTree()
{
	int data[MAX]   = {0};		//记录标志符相对应简单合取式的角码
	int data_1[MAX] = {0};
	int data_2[MAX] = {0};
	int key = 0;		//暂时保存角码
	int i = 0;
	int j = 0;
	int k = 1;			//记录当前的二进制码
	int t = 0;
	link node    = NULL;
	link newnode = NULL;

⌨️ 快捷键说明

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