• 关于大模拟


    #include<bits/stdc++.h>
    #warning Tab and SPace !!!
    using namespace std;
    const int N = 500+10, V = 50 + 5, L = 1000 + 10;
    enum{C_root, C_prevar, C_set, C_print, C_if, C_for, C_while, C_innerprevar};
    enum{V_arr, V_var};
    enum{L_lt, L_gt, L_le, L_ge, L_eq, L_neq};
    enum{E_lo, E_nu};
    using Tp = int;
    struct Error_s{
    	void throwit(string x){
    		cerr<< x << endl;
    		abort();
    	}
    }Error;
    string trim(const string& str){
    	int p1 = str.find_first_not_of(' ');
    	int p2 = str.find_last_not_of(' ');
    	return str.substr(p1, p2 - p1 + 1);
    }
    vector<string> split(string str, char ch = ' '){
    	vector<string> ret;
    	int lst = 0;
    	while(lst <= str.length()){
    		int nxt = str.find_first_of(ch, lst);
    		if(nxt == -1) break;
    		ret.push_back(str.substr(lst, nxt - lst));
    		lst = nxt + 1;
    	}
    	if(lst != str.length()) ret.push_back(str.substr(lst));
    	return ret;
    }
    template<typename Tp>
    vector<string> split(string str, Tp chk){
    	vector<string> ret;
    	int lst = 0;
    	for(int i = 0; i < str.length(); ++i){
    		if(!chk(str[i])){
    			if(lst != i)ret.push_back(str.substr(lst, i - lst));
    			ret.push_back(str.substr(i, 1));
    			lst = i + 1;
    		}
    	}
    	if(lst != str.length()) ret.push_back(str.substr(lst));
    	return ret;
    }
    struct VaribleBase{
    	typedef pair<int, int> pii;
    	struct ArrBase{
    		Tp data[V];
    		int l, r;
    		void init(int l_, int r_){
    			l = l_, r = r_;
    		}
    		Tp& Val(int x){
    			if(x < l){
    				Error.throwit("VariableBase :: ArrBase :: Val() : Invaild Array Place.");
    			}
    			return data[x - l];
    		}
    	}ArrBasePool[V];
    	struct VarBase{
    		Tp val;
    		void init(){
    			;
    		}
    		Tp& Val(){
    			return val;
    		}
    	}VarBasePool[V];
    	int arrcnt, varcnt;
    	unordered_map<string, pii> mp;
    	void init(int opt, string x, int l = -1, int r = -1){
    		if(opt == V_arr) {
    			++arrcnt;
    			mp[x] = {opt, arrcnt};
    			ArrBasePool[arrcnt].init(l, r);
    		}else if(opt == V_var){
    			++varcnt;
    			mp[x] = {opt, varcnt};
    			VarBasePool[varcnt].init();
    		}
    	}
    	Tp& Val(string s, int x = -1){
    		if(mp[s].second ==0){
    			Error.throwit("VaribleBase::Val() : Variable is not defined.");
    		}	
    		if(mp[s].first == V_arr){
    			return ArrBasePool[mp[s].second].Val(x);
    		}else if(mp[s].first == V_var){
    			return VarBasePool[mp[s].second].Val();
    		}
    		abort();
    	}
    }VariablePool;
    bool GeneralLegalCheck(char ch){
    	return islower(ch) || isupper(ch) ||isdigit(ch) ||  ch == '[' || ch == ']';
    }
    bool isNumber(string s){
    	for(auto ch : s){
    		if(!isdigit(ch)) return false;
    	}
    	return true;
    }
    bool isLegal(string s){
    	for(auto ch : s){
    		if(!GeneralLegalCheck(ch)) return false;
    	}
    	return true;
    }
    template<typename T>
    bool isLegal(string s, T check){
    	for(auto ch : s){
    		if(!check(ch)) return false;
    	}
    	return true;
    }
    struct ExpressionBase{
    	static Tp& ValRef(string s){
    		int p1 = s.find_first_of('[');
    		int p2 = s.find_first_of(']');		
    		if(p1 == -1) return VariablePool.Val(s);
    		return VariablePool.Val(s.substr(0, p1), Val(s.substr(p1 + 1, p2 - p1 - 1)));
    	}
    	static Tp Val(string s){
    		if(!isLegal(s)) {
    			Error.throwit(string("Expression :: Val(string) : Variable is not legal"));
    		}
    		if(isNumber(s)) return stoi(s);
    		return ValRef(s);
    	}
    	static int Numeric(string arg){
    		auto ret = split(arg, GeneralLegalCheck);
    		int op = 1;
    		int rval = 0;
    		for(string x : ret){
    			if(!isLegal(x)){
    				if(x[0] == '+') op = 1;
    				else if(x[0] == '-') op = -1;
    			}else {
    				rval += op * Val(x);
    			}
    		}
    		return rval;
    	}
    	static int LogicalTrans(string comp){
    		if(comp == "neq"){
    			return L_neq;
    		}else if(comp == "eq"){
    			return L_eq;
    		}else if(comp == "gt"){
    			return L_gt;
    		}else if(comp == "lt"){
    			return L_lt;
    		}else if(comp == "ge"){
    			return L_ge;
    		}else if(comp == "le"){
    			return L_le;
    		}else{
    			Error.throwit(string("ExpressionBase :: LogicalTrans(string) : Invaild Logical Operator."));
    		}
    		abort();
    	}
    	static bool Compare(string arg1, string arg2, string comp){
    		int opt = LogicalTrans(comp);
    		int v1 = Numeric(arg1), v2 = Numeric(arg2);
    		switch(opt){
    			case L_neq: return v1 != v2;
    			case L_eq : return v1 == v2;
    			case L_gt : return v1 > v2;
    			case L_lt : return v1 < v2;
    			case L_ge : return v1 >= v2;
    			case L_le : return v1 <= v2;
    		}
    		Error.throwit(string("Invaild Compare"));
    		abort();
    	}
    	static bool Logical(string arg){
    		auto chk = [&](char ch){return GeneralLegalCheck(ch) || ch == '+' || ch == '-' || ch == ' ';};
    		auto ret = split(arg, chk);
    		string args[5];
    		int cnt = 0;
    		for(auto x : ret){
    			assert(cnt <= 3);
    			if(isLegal(x, chk)){
    				args[++cnt] = trim(x);
    			}
    		}
    		return Compare(args[2], args[3], args[1]);
    	}
    	static int GetExpressionType(string s){
    		if(s.find(',') != -1) return E_lo;
    		else return E_nu;
    	}
    	static int Calc(string arg){
    		if(GetExpressionType(arg) == E_nu) return Numeric(arg);
    		return Logical(arg);
    	}
    };
    struct Command{
    	int opt;
    	string arg;
    	void Run(){
    		if(opt == C_print){
    			cout << ExpressionBase::Calc(arg) << " ";
    		}else if(opt == C_set){
    			auto chk = [&](char ch){return GeneralLegalCheck(ch) || ch == '+' || ch == '-' || ch == ' ';};
    			auto ret = split(arg, chk);
    			int cnt = 0;
    			string args[5];
    			for(string x : ret){
    				if(isLegal(x, chk)){
    					++cnt;
    					args[cnt] = trim(x);
    				}
    			}
    			ExpressionBase::ValRef(args[1]) = ExpressionBase::Calc(args[2]);
    		}
    	}
    };
    void putspc(int x){
    	for(int i = 1; i <= x; ++i) cerr<<"*";
    }
    struct CommandBlock{
    	int opt;
    	string exp;
    	vector<CommandBlock> coms;
    	string arg;
    	string argext;
    	void init(){
    		if(opt == C_for){
    			auto ret = split(arg, ',');
    			assert(ret.size() == 3);
    			for(int i = 0; i < 3; ++i) ret[i] = trim(ret[i]);
    			exp = "le, " + ret[0] + ", " + ret[2];
    			arg = ret[0] + ", " + ret[1];
    			argext = ret[0] + "," + ret[0] + "+1";
    		}
    	}
    	static string opt_to_string(int opt){
    		if(opt == C_for){
    			return "for";
    		}else if(opt == C_if){
    			return "if";
    		}else if(opt == C_while){
    			return "while";
    		}else if(opt == C_root){
    			return "root";
    		}else if(opt == C_set){
    			return "set";
    		}else if(opt == C_print){
    			return "print";
    		}else if(opt ==C_innerprevar){
    			return "innnerprevar";
    		}else if(opt == C_prevar){
    			return "prevar";
    		}
    		return "Unknown Function";
    	}
    	void debug(int x){
    		putspc(x); cerr<<  opt_to_string(opt) << " : "<<exp <<" : " <<arg << endl;
    		for(auto y : coms){
    			y.debug(x + 1);
    		}
    	}
    	void Run(){
    		if(opt == C_root){
    			for(auto x : coms){
    				x.Run();
    			}
    		}else if(opt == C_prevar){
    			for(auto x : coms){
    				x.Run();
    			}
    		}else if(opt == C_print){
    			Command tmp = {C_print, arg};
    			tmp.Run();
    		}else if(opt == C_innerprevar){
    			int p = arg.find("array");
    			if(p == -1){
    				p = arg.find(":");
    				VariablePool.init(V_var, arg.substr(0, p - 1 - 0 + 1));
    			}else{
    				p = arg.find("..");
    				int k = arg.find(",");
    				auto lstr = arg.substr(k + 1, p - 1 - (k + 1) + 1), rstr = arg.substr(p + 2, arg.length() - 1 - (p + 2));
    				lstr = trim(lstr), rstr = trim(rstr);
    				int l =	ExpressionBase::Val(lstr);
    				int r = ExpressionBase::Val(rstr);
    				p = arg.find(":");
    				VariablePool.init(V_arr, arg.substr(0, p - 1 - 0 + 1), l, r);
    			}
    		}else if(opt == C_set){
    			Command tmp = {C_set, arg};
    			tmp.Run();
    		}else if(opt == C_if){
    			if(ExpressionBase::Calc(exp)){
    				for(auto x : coms){
    					x.Run();
    				}
    			}
    		}else if(opt == C_while){
    			while(ExpressionBase::Calc(exp)){
    				for(auto x : coms){
    					x.Run();
    				}
    			}
    		}else if(opt == C_for){
    			Command tmp = {C_set, arg};
    			tmp.Run();
    			while(ExpressionBase::Calc(exp)){
    				for(auto x : coms){
    					x.Run();
    				}
    				tmp = {C_set, argext};
    				tmp.Run();
    			}
    		}else{
    			Error.throwit("CommandBlock:: Run() : Invaild Command type.");
    		}
    	}
    }root;
    string inp[N];
    int n;
    void input(){
    	while(!cin.eof()) ++n, getline(cin, inp[n]);
    }
    pair<CommandBlock,int> analyze(int p, bool ignore){
    	CommandBlock cur;
    	for(int i = p; i <= n; ++i){
    		if(inp[i].find('{') != -1){
    			if(ignore) {
    				if(inp[i].find("while") != -1){
    					int p = inp[i].find("while");
    					cur.opt = C_while;
    					cur.exp = inp[i].substr(p + 5);
    					cur.init();
    				}
    				else if(inp[i].find("vars") != -1) cur.opt = C_prevar;
    				else if(inp[i].find("hor") != -1){
    					int p = inp[i].find("hor");
    					cur.opt = C_for;
    					cur.arg = inp[i].substr(p + 3);
    					cur.init();
    				}else if(inp[i].find("ihu") != -1){
    					int p = inp[i].find("ihu");
    					cur.opt = C_if;
    					cur.exp = inp[i].substr(p + 3);
    				}
    				ignore = false;
    			}
    			else{
    				auto ret = analyze(i, true);
    				cur.coms.push_back(ret.first);
    				i = ret.second;
    			}
    		}else if(inp[i].find("set") != -1){
    			int p = inp[i].find("set");
    			CommandBlock tmp;
    			tmp.opt = C_set;
    			tmp.arg = trim(inp[i].substr(p + 3));
    			cur.coms.push_back(tmp);
    		}else if(inp[i].find("yosoro") != -1){
    			int p = inp[i].find("yosoro");
    			CommandBlock tmp;
    			tmp.opt = C_print;
    			tmp.arg = trim(inp[i].substr(p + 6));
    			cur.coms.push_back(tmp);
    		}
    		else if(inp[i].find('}') != -1) return {cur, i};
    		else if(inp[i].find("int") != -1){
    			CommandBlock tmp;
    			tmp.opt = C_innerprevar;
    			tmp.arg = trim(inp[i]);
    			cur.coms.push_back(tmp);
    		}
    	}
    	return {cur, n};
    }
    int main(){
    	input();
    	CommandBlock root = analyze(1, false).first;
    	root.opt = C_root;
    	root.Run();
    	return 0;
    }
    

    调试的时候有一个莫名奇妙的错误:我习惯性用TAB缩进,这个语言用空格,导致我处理空格的时候没有去掉TAB,所有变量名前面都挂着个空格,一调用就会
    VaribleBase::Val() : Variable is not defined.
    因为这个调了20min,真是淦

  • 相关阅读:
    损失函数 代价函数 评分函数 目标函数
    python目录索引
    机器学习/深度学习资料合集
    Git笔记
    目标检测中的正负样本分配
    map计算
    nms
    08shell脚本
    07makefile文件
    05-STL
  • 原文地址:https://www.cnblogs.com/cdsidi/p/16751134.html
Copyright © 2020-2023  润新知