采用程序实现逻辑表达式

//最大缺点没保存堆栈 优化的方法 
#include <iostream>
#include <string>
#include <regex>
#include <list>
#include <algorithm>
#include <string.h>


using namespace std;


typedef long long ll;


class Expression 
{
protected:
Expression* left;
Expression* right;
string op;
public:
virtual ll calculate()
{
throw exception("calculate not implemented");
};


virtual string toJSON()
{
throw exception("toJSON not implemented");
}
};






class Logical : public Expression 
{
friend class Parser;
public:
Logical(string op, Expression* left, Expression* right) 
{
this->op = op;
this->left = left;
this->right = right;
}


static bool check(string op) {
regex e("(and|or|xor)", regex_constants::icase);
return regex_match(op, e);
}


ll calculate()
{
ll r1 = left->calculate();
ll r2 = right->calculate();
if (_strcmpi(op.c_str(), "and") == 0) return ((r1 > 0) && (r2 > 0)) ? 1 : 0;
if (_strcmpi(op.c_str(), "or") == 0)  return ((r1 > 0) || (r2 > 0)) ? 1 : 0;
if (_strcmpi(op.c_str(), "xor") == 0) return ((bool)r1 ^ (bool)r2) ? 1 : 0;
throw exception("logical NONE");
}
};


//gu
class Relation : public Expression 
{
friend class Parser;
public:
Relation(string op, Expression* left, Expression* right) 
{
this->op = op;
this->left = left;
this->right = right;
}


static bool check(string op) 
{
regex e("(<=|>=|\\/=|!=)|([><=])", regex_constants::icase);
return regex_match(op, e);
}


ll calculate()
{
ll r1 = left->calculate();
ll r2 = right->calculate();


if (op == "<")  return r1 < r2  ? 1 : 0;
if (op == "<=") return r1 <= r2 ? 1 : 0;
if (op == ">")  return r1 > r2  ? 1 : 0;
if (op == ">=") return r1 >= r2 ? 1 : 0;
if (op == "==") return r1 == r2 ? 1 : 0;
if (op == "!=" ||op == "/=") return r1 != r2 ? 1 : 0;
throw exception("relation NONE");
}
};




class Factor : public Expression 
{
friend class Parser;
public:
Factor(string op, Expression* left, Expression* right) 
{
this->op = op;
this->left = left;
this->right = right;
}


static bool check(string op) 
{
return op == "*" || op == "/";
}


ll calculate() {
ll r1 = left->calculate();
ll r2 = right->calculate();


if (op == "*") return r1 * r2;
if (op == "/") return r1 / r2;
throw exception("factor NONE");


}
};




class Term : public Expression
{
friend class Parser;
public:
Term(string op, Expression* left, Expression* right) 
{
this->op = op;
this->left = left;
this->right = right;
}


static bool check(string op) 
{
return op == "+" || op == "-";
}


ll calculate() 
{
ll r1 = left->calculate();
ll r2 = right->calculate();


if (op == "+") return r1 + r2;
if (op == "-") return r1 - r2;
throw exception("term NONE");
}
};




class Primary : public Expression 
{
friend class Parser;
};




class Integer : public Primary 
{
ll value;
friend class Parser;
public:
Integer(ll v) : value(v) {}
ll calculate() { return value; }
};




class Parentesized : public Primary 
{
Expression expression;
friend class Parser;
public:
ll calculate() { return expression.calculate(); }
};




//nParm1>100&&nParam<1000


class Parser 
{
private:
string input;
list<string> tokens;
list<string>::iterator token;


void tokenize(string s) 
{
regex token("(and|or|xor)|(<=|>=|\\/=|!=)|([><=])|([\\+\\-\\*\\/])|([0-9]+)|([()])", regex_constants::icase);
smatch m;


while (regex_search(s, m, token)) 
{
tokens.push_back(m.begin()->str());
s = m.suffix().str();
}


if (tokens.size() == 0) 
throw exception("wrong syntax");
}




Expression* parseLogical() 
{
Expression* left = parseRelation();
while (true) 
{
string op;
if (token != tokens.end()) 
op = *token;


if (Logical::check(op)) 
{
token++;
Expression* right = parseRelation();
left = new Logical(op, left, right);
}
else 
{
break;
}
}
return left;
}


Expression* parseRelation() 
{
Expression* left = parseTerm();
while (true)
{
string op;
if (token != tokens.end()) 
op = *token;


if (Relation::check(op))
{
token++;
Expression* right = parseTerm();
left = new Relation(op, left, right);
}
else 
{
break;
}
}
return left;
}


Expression* parseTerm() 
{
Expression* left = parseFactor();
while (true) 
{
string op;
if (token != tokens.end()) 
op = *token;


if (Term::check(op))
{
token++;
Expression* right = parseFactor();
left = new Term(op, left, right);
}
else
{
break;
}
}
return left;
}


Expression* parseFactor() 
{
Expression* left = parsePrimary();
while (true) 
{
string op;
if (token!=tokens.end())
op = *token;


if (Factor::check(op)) 
{
token++;
Expression* right = parsePrimary();
left = new Factor(op, left, right);
}
else 
{
break;
}
}
return left;
}


Expression* parsePrimary() 
{
Expression* result;
try
{
// number
result = new Integer(stoll(*token));
token++;
}
catch (const std::invalid_argument& e) 
{
// not a number
if (*token == "(") 
{
token++;
result = parse();
token++; // skip ")"
}
else {
throw exception("syntax error (primary)");
}
}
return result;
}




public:
Parser(string s) :input(s) 
{
tokenize(s);
token = tokens.begin();
}


Expression* parse() 

return parseLogical(); 
}
};




void main() 
{
try {
time_t t_start, t_end;
t_start = time(NULL) ;
for (int i = 0; i < 1000; i++)
{
// string input = "555/5 + 1 -100";
string input = "((5>=5)&(5<8))";
Parser *p = new Parser(input);
Expression* tree = p->parse();
ll result = tree->calculate();


}
t_end = time(NULL) ;
printf("time: %.0f s\n", difftime(t_end,t_start)) ;


string str2 = "((5>=5)&(5<8))";


Parser *p2 = new Parser(str2);
Expression* tree2 = p2->parse();
ll result2 = tree2->calculate();


system("PAUSE");


}
catch (const exception& e) {
cout << e.what() << endl;
}
system("pause");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值