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

📄 logiccal.h

📁 逻辑运算类:支持与或非逻辑运算
💻 H
字号:

//逻辑表达式求值 支持'&' '|' '!' '(' ')' 
//变量标识符'd' 例如d1 -  1, d0  - 0  d22  - 22 数据为不大于10位的整数

//源程序清单
//#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define ERROR           -1
#define BLANK           0
#define DATA            1
#define KUOHAO1         5
#define KUOHAO2         2
#define ADD_OR_SUB      3
#define MUT_OR_DIV      4
#define PREDATA         6
#define DATA_MAXSIZE    10

//char Exp[EXPMAXSIZE] = "d1|(d0&d3)|d0|(!d22);";

template <class Elem>class Stack;
template <class Elem>
class StackNode //堆栈的结点类
{
	friend class Stack<Elem>;
	Elem elem;
	StackNode<Elem> *link;
	StackNode (Elem e=0, StackNode<Elem> *l=NULL):elem(e),link(l)
	{
		//cout<<"elem is : "<<e<<endl;
	}
};
template <class Elem>
class Stack
{
	int number;
	StackNode<Elem> *head;

public:
	Stack():number(0),head(NULL){}
	~Stack()
	{
		StackNode<Elem> *tmp=head;
		while(head!=NULL)
		{
			head=head->link;
			delete tmp;
			tmp=head;
		}
	}

	void Push(const Elem &e)
	{
		number++;
		head=new StackNode<Elem>(e, head);
	}
	void MakeEmpty()
	{
		StackNode<Elem> *tmp=head;
		while(head!=NULL)
		{
			head=head->link;
			delete tmp;
			tmp=head;
		}
		number=0;
	}

	void Pop()
	{
		assert(number!=0);
		number--;
		StackNode<Elem> *tmp=head; 
		head=head->link;
		delete tmp;
	}

	Elem GetHead()
	{
		return head->elem;
	}
int GetNumber() const { return number; }//返回堆栈中元素的数目
};

//计算类
class Caculator
{
private:
	Stack<double> data;//数据栈
	Stack<char> sign;//运算符栈
	int flag; //标志位表示前一个输入的是数还是一个运算符
	char *pExpress;
public:
	Caculator()
	{
		flag=BLANK;
		pExpress = NULL;
	}
	Caculator(char *pbuf)
	{
		flag = BLANK;
		pExpress = pbuf;
	}
	~Caculator(){}
	int Prior(char ch) const// 返回运算符的优先级
	{
		switch(ch)
		{
		case ')': return 1;
	/*	case '+':
		case '-': return 2;*/
		case '!':
		case '|':
		case '&': return 2;
		case '*':
		case '/': return 3;
		case '(': return 5;
		default: return -1;
		}
	}

	void clearstream()// 清空输入流
	{
//		char ch;
//		while(cin>>ch, ch!=';') ;
	}
	void done(char ch)//做一次二元运算
	{
		double a, b;
		a=data.GetHead(); data.Pop();
		b=data.GetHead(); data.Pop(); 

		switch(ch)
		{
		/*	case '+': b+=a;break;
			case '-': b-=a;break;
			case '*': b*=a;break;
			case '/': b/=a;break;*/
		    case '!': b = !a; break;
			case '|': b =(b||a);break;
			case '&': b =(b&&a);break;
			default : break;
		}
		data.Push(b);
	}

	char* Caculate()//计算主体
	{
		char ch;
		double d;
		char cha[DATA_MAXSIZE];
		int k=0;
		bool bfind1=0;
	/*	for(int j=0;j<EXPMAXSIZE;j++)
		{
			if(Exp[j]==';')
			{
				bfind1 =1;
				break;
			}
		}*/
		int i=0;
		while(pExpress[i]!='\0')
		{
			if(pExpress[i]==';')
			{
				bfind1 = 1;
				break;
			}
			i++;
		}
		if(bfind1==0)
		{
//			cout<<"Error input! 表达式缺少结束符';'"<<endl;
			flag=ERROR;
			clearstream();
			return "表达式缺少结束符!";
		}
		while(ch = pExpress[k],k++,ch!=';')
	//while(cin>>ch, ch!=';')
		{ 
			
		//	if(ch>='0' && ch<='9' || ch=='.')//如果是一个0-9的数, 则输入一个实数
			if(ch== 'd')
			{
				if(flag==DATA)
				{ 
			//		cout<<"Error input! 数字连写了"<<endl;
					flag=ERROR;
					clearstream();
					return "数字连写了!";
				}

		//		cin.putback(ch);
		//		cin>>d;
		//		d = atof(&ch);
				bool bFind = 0;
				for(int i=0;i<DATA_MAXSIZE;i++)
				{
					if( pExpress[k+i]>='0' &&  pExpress[k+i]<='9')
					{
						cha[i] = pExpress[k+i];
						bFind = 1;
					}
					else
						break;
				}
				if(bFind)
				{
					k = k+i;
					d = atof(cha);
					data.Push(d);
					flag=DATA;
				}
				else
				{
			//		cout<<"Error input! 标识符后少了数据"<<endl;
					flag = ERROR;
					clearstream();
					return "标识符后少了数据!";
				}
			}
			else if(ch>='0' && ch<='9')//如果是一个0-9的数, 则输入一个实数
			{
		//		cout<<"Error input! 数据前少了标识符"<<endl;
				flag = ERROR;
				clearstream();
				return "数据前少了标识符!";
			}
			else//如果输入的是字符, 则作出判断
			{
				int prio=Prior(ch);
				char tempch, chprior;
				switch( prio )
				{
					case -1: 
					//	cout<<"Error input! 不允许的字符"<<endl;//非法字符
						flag=ERROR; 
						clearstream();
						return "不允许的字符!";

					case 1: // 如果是一个后括号,
						if(flag==ADD_OR_SUB || flag==MUT_OR_DIV)//如果运此括号前是一个运算符,则提示出错
						{
							flag=ERROR;
							clearstream();
						//	cout<<"Error input! 运算符后少了数据"<<endl;
							return "运算符后少了数据!";
						}
							//如果它前面的是前括号,则表明括号中间没在数据,提示出错
						if( flag==KUOHAO1 )
						{
						//	cout<<"ERROR! 括号中间没在数据"<<endl;
							flag=ERROR;
							clearstream();
							return "括号中间没在数据!";
						}
						tempch=sign.GetHead(); //是合法的运算, 取一个运算符
						flag=KUOHAO2;

						while(tempch!='(') //做完这一重括号内的所有运算
						{ 
							sign.Pop();
							done(tempch); 
							if(sign.GetNumber()!=0)
							{

								tempch=sign.GetHead();

							}
							else //如果当前的后括号没有找到与其配对的前括号, 则提示出错
							{
						//		cout<<"Error input! 括号不配对"<<endl;
								flag=ERROR;
								clearstream();
								return "括号不配对!";
							}

						}
						sign.Pop();
						break;
					case 2: //如果读入的是一个 + 或者 - 号,

						//它前面的是一个 + 或者 - 号, 由提示出错
						if(flag==ADD_OR_SUB || flag==MUT_OR_DIV ) 
						{ 
							cout<<"Error input! 运算符连用"<<endl;
							flag=ERROR;
							clearstream();
							return "运算符连用!"; 
						}
							//如果+前面没有数据,或者+是被写在括号里的,则向它的前面压入一个0到data
						if( flag==BLANK || data.GetNumber() == 0 || flag == KUOHAO1 )
						{
						//	data.Push(0);//push 0 to stack
							if(ch=='|') data.Push(0);
							else if(ch=='&') data.Push(1);
							else if(ch=='!') data.Push(0);

						}
							//如果它前面是一个后括号,因后括号里的内容已经做过运算,故只当一个一般的来做
						if( flag== KUOHAO2 || flag == DATA )
						{
							while( sign.GetNumber() && sign.GetHead()!='(' && Prior( sign.GetHead() ) >= Prior(ch) )
							{
								done( sign.GetHead() );
								sign.Pop();
							}
						}
						flag = ADD_OR_SUB;
						sign.Push( ch );
						break;

					case 3: // 如果当前输入是一个 * 或者 / 号
						//如果前一个输入是一个 * 或者 / 号
						if(flag==MUT_OR_DIV || flag==ADD_OR_SUB )
						{
							cout<<"Error input! 运算符连用"<<endl;
							flag=ERROR; 
							clearstream();
							return "运算符连用!"; 
						}
						//如果前面是一个前括号
						if( flag==KUOHAO1 )
						{
							cout<<"ERROR! * / 不能直接接在( 后"<<endl;
							flag=ERROR;
							clearstream();
							return "* / 不能直接接在( 后!";
						}
						//如果它放在了表达式的开头
						if(data.GetNumber()==0)
						{ 
							cout<<"Error input! * 或 / 不能放在表达式的开头"<<endl;
							flag=ERROR; 
							clearstream();
							return "* 或 / 不能放在表达式的开头!"; 
						}
							//如果它前面不只一个数字, 则做它前面的运算
						if(data.GetNumber()!=1)
						{
							chprior=Prior(sign.GetHead());
							if(chprior>=Prior(ch) && sign.GetHead()!='(')
							{
								chprior=sign.GetHead(); 
								sign.Pop();
								done(chprior);
							}
						}
						sign.Push(ch);
						flag=MUT_OR_DIV;
						break;
					case 5://如果当前的是一个前括号
					// 如果它前面输入的是一个数据,则提示出错
						if(flag==DATA)
						{
						//	cout<<"Error input! 数据后不能直接跟括号"<<endl; 
							flag=ERROR; 
							clearstream();
							return "数据后不能直接跟括号!";
						}
						sign.Push(ch); 
						flag=KUOHAO1; 
						break;
					default :
				//		cout<<"Error input! 非法字符: "<<ch<<endl;
						flag=ERROR;
						clearstream();
						return "非法字符!";
						break;
				}
			}
		}
		if( sign.GetNumber() && sign.GetHead() == '(' )
		{
		//	cout<<"ERROR! 括号不配对!"<<endl;//前括号没有找到后括号
			flag=ERROR; 
			return "括号不配对!";
		}
		if( flag==MUT_OR_DIV || flag == ADD_OR_SUB)
		{
		//	cout<<"ERROR!表达式没有写完"<< endl;
			flag=ERROR;
			return "表达式没有写完!";
		}
		while(sign.GetNumber())
		{
			if( sign.GetHead() == '(' )
			{
		//		cout<<"ERROR! 括号不配对!"<< endl;
				flag = ERROR;
				return "括号不配对!!";
			}
			done(sign.GetHead());
			sign.Pop();
		}
		return "表达式正确!";
	}

	int OutPut()
	{
		int ans=0;
		if(flag==ERROR)
		{
		//	cout<<"输入错误<! NO ANSWER !>"<<endl;
			ans = -1;
		}
		else if(data.GetNumber()==0)
		{ 
		//	cout<<"空表达式:无结果!"<<endl;
			ans = -2;
		}
		else
		{
		//	cout<<" 答 案 = "<<data.GetHead()<<endl;
			ans = (int)data.GetHead();
			data.Pop();
		}
		return ans;
	}

	void EnEmpty()
	{
		data.MakeEmpty();
		sign.MakeEmpty();
		flag=BLANK;
	}
};

⌨️ 快捷键说明

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