| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 | #include "stdafx.h"#include<iostream>  #include<stack>  #include<queue>  #include<cstring>#include<vector>#include<map>#include "MathExpression.h"#include "XMLSerialization.h"#include "COTSUtilityDllFunExport.h"using namespace std;namespace expInterpreter {	namespace {		int CountStr(std::string T, std::string P)		{			int count = 0;			int begin = 0;			while ((begin = T.find(P, begin)) != string::npos)			{				count++;				begin = begin + P.length();			}			return count;		}		void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c)		{			std::string::size_type pos1, pos2;			pos2 = s.find(c);			pos1 = 0;			while (std::string::npos != pos2)			{				v.push_back(s.substr(pos1, pos2 - pos1));				pos1 = pos2 + c.size();				pos2 = s.find(c, pos1);			}			if (pos1 != s.length())				v.push_back(s.substr(pos1));		}		void DevidExpToMathExp(std::vector<std::pair<string,string>>& mathExp, string exp)		{			xmls::ReplaceAll(exp, " ", "");			std::vector<string> list1;						SplitString(exp, list1, "and");			for (auto s : list1)			{				if (s.find("or") != std::string::npos)				{					std::vector <string> list2;					SplitString(s, list2, "or");					for (auto s1 : list2)					{					std:: pair<string, string> p1;						p1.first = s1;						p1.second = s1;						mathExp.push_back(p1);					}				}				else				{				std::pair<string, string> p2;					p2.first = s;					p2.second = s;					mathExp.push_back(p2);				}			}			for (auto s2 = mathExp.begin(); s2 != mathExp.end(); s2++)			{				int startPos;				int sMathLen;				string sMath;				int n1 = CountStr(s2->second, "(");				int n2 = CountStr(s2->second, ")");				if (n1 > n2)//contains unpaired "(" 				{					startPos = n1 - n2;					sMathLen = s2->second.length() - startPos;					sMath = s2->second.substr(startPos, sMathLen);					s2->second = sMath;					s2->first = sMath;				}				else if (n2 > n1)				{					startPos = n2 - n1;					sMathLen = s2->second.length() - startPos;					sMath = s2->second.substr(0, sMathLen);					s2->second = sMath;					s2->first = sMath;				}			}		}						int f(char c) // 求表达式的优先级  		{			if (c == '(') return 4;			if (c == '!') return 3;			if (c == '&') return 2;   // 相当于*			if (c == '|') return 1;   // 相当于+,优先级最低			else				return 0;		}		bool f2(char c) // 逻辑表达式数的转换		{			if (c == 'F')			{				return false; //  F相当于0			}			else			{				return true;            //  V相当于1			}		}		string MidToPost(const char* c)      //求表达式对应的后缀表达式   		{			stack<char> s;           //字符串中去手动去空格			string q = "";			int n = strlen(c);			for (unsigned int i = 0; i < n; i++)			{				if (c[i] != ' ')     // 除去空格 				{					// 如果遇到运算数,直接加入到队列中,用队列来放后缀表达式 					if (c[i] == 'F' || c[i] == 'V')					{						q += c[i];					}					else if (c[i] == '!' && !s.empty() && s.top() == '!')					{						s.pop();     // 如果遇到!而且栈顶也是!那么直接抵消出栈					}					else if (!s.size())					{						s.push(c[i]); // 如果栈为空,遇到运算符直接入栈 					}					else if (c[i] == ')')					{                 // 如果是右括号,则弹出对应左括号前的所有的运算符 ,加入到队列中 						while (s.top() != '(')						{							q += s.top();							s.pop();						}						s.pop();      // 弹出左括号						continue;					}					else if (f(s.top()) == 4 || (f(c[i]) > f(s.top())))					{						s.push(c[i]);  // 如果栈顶是左括号,或者当前优先级高,都入栈					}					else if (f(s.top()) != 4 && f(c[i]) <= f(s.top()))					{						q += s.top();						s.pop();              // 如果遇到运算符没有栈顶运算符级别高,出栈 						while (!s.empty() && f(s.top()) != 4 && f(c[i]) <= f(s.top()))						{							q += s.top();  // 从栈中弹出比当前优先级高的运算符							s.pop();						}						s.push(c[i]);  //将当前运算符加入到队列 					}				}			}			while (!s.empty())			{				q += s.top();      // 最后将栈里面所有元素弹出加入到队列				s.pop();			}			return q;		}		char GetValuePost(string q)		{                                //后缀表达式求值   			bool r = true;			char x, y, ans;			ans = 'F';			stack<char> s;			int n = q.size();			for (unsigned int i = 0; i < n; i++)			{				if (q[i] == 'V' || q[i] == 'F')				{					s.push(q[i]);				}				else				{					if (q[i] == '&')					{						x = s.top();						s.pop();						y = s.top();						s.pop();						bool v1, v2;						v1 = f2(x);						v2 = f2(y);						r = (v1 && v2);						if (r == true)							s.push('V');						else							s.push('F');					}					else if (q[i] == '|')					{						x = s.top();						s.pop();						y = s.top();						s.pop();						r = (f2(x) || f2(y));						if (r == true)							s.push('V');						else							s.push('F');					}					else					{						x = s.top();						s.pop();						if (f2(x) == 1)							s.push('F');						else							s.push('V');					}				}				ans = s.top();			}			return ans;		}	/*	void	RemoveLeftAndRightBrace(std::string& s)		{				}*/			}	/*int main1()	{*/		//"(Si+Al+Na)>60 and O>15 and ASPECT>10 and D_MEAN<20"		//"(20+21+22)>60 and 16>15 and (5>10 and 10<20)"		//"(20+21+22)>60 and 16>15 and (5>10 or 10<20)"	/*	std::string hybrids = "20+(5+1)*25-500>60 and (21>15 and (5>10 or 10<20))";		bool v = CalcuExp(hybrids);		cout << v << endl;*/	/*}*/	bool CalcuExp(std::string hybrids)	{		//hybrids = "(51.839426 + 34.298664) > 90and34.298664 > 30and51.839426 > 40and0 < 1.5and0 < 1.5and8.452528 < 3and5.409383 < 2and0 < 2and0 < 2and0 < 2and51.839426 < 60and2.809600 < 1.6";		//hybrids = "(26.856649 + 23.877375 + 0.000000) > 30 and (0.000000 + 26.856649) > 5 and 23.877375 > 5 and 19.041451 < 5 and 13.989637 < 10";		//hybrids = "(0 < 1or0 > 50)and0.925024 >= 15and0.925024 <= 100and48.318507 >= 20and48.318507 <= 100and0 < 5";		//hybrids = "(19.445164 + 0.950784) >= 80and0.950784 / 19.445164 >= 0.4and0.950784 / 19.445164 < 6.2and0 < 3and0 < 3and0.411897 < 3and0 < 3and0 < 5and0 < 10and0 < 5and0 < 5";		xmls::ReplaceAll(hybrids, " ", "");		expInterpreter::Expression mathExpIpr;		std::vector<std::pair<string,string>> mathexp;		DevidExpToMathExp(mathexp, hybrids);//first ,we devid the expression into math expressions such as "20+(5+1)*25-500>60" ,we use "and" and "or" to separate it.				for (auto e : mathexp)		{			string rst;			string s = e.second; //every string contains one logic compare sign,such as "<" or ">" etc.			/*cout << e.second << endl;*/			auto r = s.find("<");// we check which sign it contains.			auto r1 = s.find(">");			auto r2 = s.find("=");			auto r3 = s.find(">=");			auto r4 = s.find("<=");						if (r3 != std::string::npos)// firstly,wind look out the ">=" then "<=" then ">" and "<" "=" .the sequence is very important.			{				double result;				vector<string> strs;				SplitString(s, strs, ">=");				string s1 = "";				s1 = strs[0] + "-(" + strs[1] + ")";				mathExpIpr.SetExprStr(s1.c_str());				float rst1 = mathExpIpr.GetResult(&result);				if (result >= 0)				{					rst = "V";				}				else				{					rst = "F";				}			}			else if (r4 != std::string::npos)			{				double result;				vector<string> strs;				SplitString(s, strs, "<=");				string s1 = "";				s1 = strs[0] + "-(" + strs[1] + ")";				mathExpIpr.SetExprStr(s1.c_str());				int rst1 = mathExpIpr.GetResult(&result);				if (result <= 0)				{					rst = "V";				}				else				{					rst = "F";				}			}else if(r != std::string::npos)//contains "<"			 			{				double result;				vector<string> strs;				SplitString(s, strs, "<");				string s1 = strs[0] + "-(" + strs[1] + ")";//convert this exp to a menus exp and calculate its value and then compare to 0.				mathExpIpr.SetExprStr(s1.c_str());				float rst1 = mathExpIpr.GetResult(&result);//calculate this expression 				if (result < 0)				{					rst = "V";				}				else				{					rst = "F";				}			}			else if (r1 != std::string::npos)			{				double result;				vector<string> strs;				SplitString(s, strs, ">");				string s1 = strs[0] + "-(" + strs[1] + ")";				mathExpIpr.SetExprStr(s1.c_str());				float rst1 = mathExpIpr.GetResult(&result);				if (result > 0)				{					rst = "V";				}				else				{					rst = "F";				}			}			else if (r2 != std::string::npos)			{				double result;				vector<string> strs;				SplitString(s, strs, "=");				string s1 = strs[0] + "-(" + strs[1] + ")";				mathExpIpr.SetExprStr(s1.c_str());				float rst1 = mathExpIpr.GetResult(&result);				if (result == 0)				{					rst = "V";				}				else				{					rst = "F";				}			}			e.second = rst;			xmls::ReplaceFirst(hybrids, e.first, e.second);		}		xmls::ReplaceAll(hybrids, "and", "&");		xmls::ReplaceAll(hybrids, "or", "|");//get a pure logic expression.				//LogTrace(__FILE__, __LINE__, hybrids.c_str());		string post;		char ans;		post = MidToPost(hybrids.c_str());		//cout << post << endl;		ans = GetValuePost(post);		if (ans == 'V')		{			return true;		}		else		{			return false;		}	}	}
 |