64,649
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <sstream>
#include <stack>
#include <deque>
#include <map>
#include <cctype>
#define BRACKET 5
#define ALPHA 4
#define LOGIC_SIGN 3
#define SIGN_2 2
#define NUMRIC 1
#define NULL_NODE 0;
using std::cin;
using std::string;
using std::vector;
using std::stringstream;
using std::ifstream;
using std::endl;
using std::ofstream;
//using std::cout;
using std::stack;
using std::deque;
using std::map;
using std::pair;
using std::isalnum;
using std::isdigit;
using std::isalpha;
ofstream cout("result.txt");
typedef double (*fx)(double,double);
typedef bool (*fz)(double,double);
map<string,int> sign_map;
map<string,int> priority_map;
map<string,fx> fx_map;
map<string,fz> fz_map;
template<typename T> void display(T t){
for(T::iterator it = t.begin();
it!=t.end();
++it)
cout<<it->ctx<<" ";
cout<<" "<<endl;
}
double f1(double d1,double d2){
return d1+d2;
}
double f2(double d1,double d2){
return d1-d2;
}
double f3(double d1,double d2){
return d1*d2;
}
double f4(double d1,double d2){
return d1/d2;
}
double f5(double d1,double d2){
return d1-floor(d1/d2)*d2;
}
bool f6(double d1,double d2){
return d1>d2;
}
bool f7(double d1,double d2){
return d1<d2;
}
bool f8(double d1,double d2){
return d1==d2;
}
bool f9(double d1,double d2){
return d1!=d2;
}
bool f10(double d1,double d2){
return d1>=d2;
}
bool f11(double d1,double d2){
return d1<=d2;
}
class Node{
public:
Node(const char c){
ctx = c;
if(isdigit(c)||c=='.')
type = NUMRIC;
else if(isalpha(c))
type = ALPHA;
else if(c=='('||c==')')
type = BRACKET;
else{
if(sign_map.find(ctx)!=sign_map.end())
type = sign_map[ctx];
else{
cout<<"unable to generate Node"<<endl;
type = NULL_NODE;
delete this;
}
}
if(type==SIGN_2||type==LOGIC_SIGN)
priority = priority_map[ctx];
cout<<"construct:"<<ctx<<endl;
}
Node(Node &n1,Node &n2){
if(n1.type==n2.type){
type = n1.type;
ctx = n1.ctx+n2.ctx;
if(type==SIGN_2||type==LOGIC_SIGN)
priority = priority_map[ctx];
}else{
cout<<"unable to generate Node"<<endl;
type = NULL_NODE;
delete this;
}
cout<<"construct:"<<ctx<<endl;
}
~Node(){
cout<<"destruct:"<<ctx<<endl;
}
operator string(){
char tmp[10];
return ctx;
}
double numric;
string ctx;
int priority;
int type;
int *n;
};
class NumricFilter{
public:
NumricFilter(const string &s):numric(0){
if(!parseInput(s))
return;
parseNum(0);
}
~NumricFilter(){
if(numric!=0)
delete [] numric;
}
void show(){
cout<<numricDesc<<endl;
for(vector<string>::iterator it = s_rule.begin();
it!=s_rule.end();
it++)
cout<<*it<<endl;
cout<<n;
}
private:
bool parseInput(const string &s){
stringstream ss;
string s1;
ss<<s;
if(!(ss>>s1))
return 0;
numricDesc = s1;
while(ss>>s1)
s_rule.push_back(s1);
const char *c = numricDesc.c_str();
for(int i=0;;i++)
if(c[i]=='\0'){
numric = new int[i];
n = i;
break;
}else{
numric_map[c[i]] = i;
}
for(unsigned int i=0;i<s_rule.size();i++)
rule.push_back(*parseRule(s_rule[i]));
cout<<"numric description : "<<numricDesc<<endl;
return 1;
}
bool checkNum(){
for(vector<vector<Node> >::iterator it = rule.begin();
it!=rule.end();
++it){
stack<double> st1;
stack<string> st2;
unsigned int i = 0;
while(i<it->size()){
Node n = (*it)[i];
if(n.type==SIGN_2||n.type==LOGIC_SIGN){
double d2 = st1.top();
st1.pop();
double d1 = st1.top();
st1.pop();
if(n.type==SIGN_2){
double d3 = fx_map[n.ctx](d1,d2);
st1.push(d3);
}else{
if(!fz_map[n.ctx](d1,d2))
return 0;
else
break;
}
}else if(n.type==NUMRIC||n.type==ALPHA){
if(n.type==NUMRIC)
st1.push(n.numric);
else
st1.push(*n.n);
}
i++;
}
}
return 1;
}
void showNum(){
for(int j=0;j<n;j++)
cout<<numric[j];
cout<<endl;
}
void parseNum(int i){
if(i>=n){
if(checkNum())
showNum();
return;
}
for(int j=0;j<10;j++){
numric[i] = j;
parseNum(i+1);
}
}
vector<Node> *parseRule(string &s){
const char * c = s.c_str();
vector<Node> *v = new vector<Node>;
//词法分析
int i = 0;
deque<Node> tmp;
tmp.push_back(*new Node(c[i++]));
while(1){
const char *cr = &c[i++];
if(*cr=='\0')
break;
Node n1 = tmp.back();
Node n2 = *new Node(*cr);
tmp.pop_back();
if(n1.type==n2.type){
Node *n3 = new Node(n1,n2);
tmp.push_back(*n3);
}else{
tmp.push_back(n1);
tmp.push_back(n2);
}
}
display<deque<Node> >(tmp);
//语法分析
stack<Node> st;
Node *n,*n2;
int pri = 0;
while(tmp.size()>0){
n = &tmp.front();
tmp.pop_front();
if(n->type==BRACKET){
if(n->ctx=="(")
pri += 10;
else if(n->ctx==")")
pri -=10;
continue;
}else if(n->type==NUMRIC||n->type==ALPHA){
v->push_back(*n);
}else if(n->type==SIGN_2||n->type==LOGIC_SIGN){
n->priority += pri;
if(st.size()==0)
st.push(*n);
else{
while(st.size()>0){
n2 = &st.top();
if(n2->priority>=n->priority){
st.pop();
v->push_back(*n2);
}else{
break;
}
}
st.push(*n);
}
}
}
while(st.size()>0){
n2 = &st.top();
st.pop();
v->push_back(*n2);
}
//数据初始化
for(vector<Node>::iterator it = v->begin();
it != v->end();
++it){
const char *sx = (it->ctx).c_str();
if(it->type==NUMRIC)
it->numric = atof(sx);
else if(it->type==ALPHA){
it->n = numric+numric_map[sx[0]];
}
}
//display<vector<Node> >(*v);
return v;
}
string numricDesc;
vector<string> s_rule;
vector<int> result;
vector<vector<Node> > rule;
int *numric;
int n;
map<char,int> numric_map;
};
int main(){
sign_map["+"] = SIGN_2;
sign_map["-"] = SIGN_2;
sign_map["*"] = SIGN_2;
sign_map["/"] = SIGN_2;
sign_map["%"] = SIGN_2;
sign_map[">"] = LOGIC_SIGN;
sign_map["<"] = LOGIC_SIGN;
sign_map["="] = LOGIC_SIGN;
sign_map["!"] = LOGIC_SIGN;
sign_map["!="] = LOGIC_SIGN;
sign_map[">="] = LOGIC_SIGN;
sign_map["<="] = LOGIC_SIGN;
priority_map["+"] = 2;
priority_map["-"] = 2;
priority_map["*"] = 4;
priority_map["/"] = 4;
priority_map["%"] = 4;
priority_map[">"] = 0;
priority_map["<"] = 0;
priority_map["="] = 0;
priority_map["!"] = 0;
priority_map["!="] = 0;
priority_map[">="] = 0;
priority_map["<="] = 0;
fx_map["+"] = f1;
fx_map["-"] = f2;
fx_map["*"] = f3;
fx_map["/"] = f4;
fx_map["%"] = f5;
fz_map[">"] = f6;
fz_map["<"] = f7;
fz_map["="] = f8;
fz_map["!="] = f9;
fz_map[">="] = f10;
fz_map["<="] = f11;
string input;
std::cout<<"usage:\n numricDescription [rules...]\nexample:\n abc a%3!=1 (a+c)*2+3*(a-b)=9"<<endl;
//getline(cin,input);
input = "abc a%3!=1 (a+c)*2+3*(a-b)=9";//test
NumricFilter nf(input);
//nf.show();
cout<<"end"<<endl;
return 0;
}