Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Sursa 100p
- /// student Tamio-Vesa N.
- #include <bits/stdc++.h>
- using namespace std;
- enum token_type {
- LBRACK = 0, RBRACK = 1, LPAR = 2, RPAR = 3, STAR = 4, INT = 5, STR = 6
- };
- struct token {
- token_type t;
- int x;
- string s;
- };
- vector<token> tokensise(string s){
- vector<token> ret;
- string current_s;
- int current_x = 0;
- int i = 0;
- static token_type tab[256];
- tab['['] = token_type::LBRACK;
- tab[']'] = token_type::RBRACK;
- tab['('] = token_type::LPAR;
- tab[')'] = token_type::RPAR;
- tab['*'] = token_type::STAR;
- ///cerr << s << endl;
- INIT:
- if(i == (int)s.size()) goto END;
- if(isdigit(s[i])){
- ///cerr << '%' << endl;
- current_x = s[i++] - '0';
- goto INTEGER;
- }
- if(isalpha(s[i])){
- current_s.push_back(s[i++]);
- goto STRING;
- }
- ret.push_back(token{ tab[(unsigned)s[i++]], 0, "" });
- goto INIT;
- STRING:
- if(isalpha(s[i])){
- current_s.push_back(s[i++]);
- goto STRING;
- }
- ret.push_back(token{ token_type::STR, 0, current_s });
- current_s.clear();
- goto INIT;
- INTEGER:
- if(isdigit(s[i])){
- current_x = 10 * current_x + s[i++] - '0';
- goto INTEGER;
- }
- ret.push_back(token{ token_type::INT, current_x, "" });
- current_x = 0;
- goto INIT;
- END:
- return ret;
- }
- enum expr_type{
- odd_pal, even_pal, repetition, basic, concat, nil
- };
- struct expr{
- expr_type t;
- string s;
- int reps;
- expr *leftson = 0, *rightson = 0;
- };
- expr* parse(vector<token>::iterator& i, vector<token>::iterator e);
- expr* parse_lbrack(vector<token>::iterator& i, vector<token>::iterator e){
- assert(i->t == token_type::LBRACK);
- expr *ret = new expr;
- ++i;
- if(i->t == token_type::STAR){
- ret->t = expr_type::even_pal;
- ++i;
- ret->leftson = parse(i, e);
- assert(i->t == token_type::RBRACK);
- ++i;
- }
- else{
- ret->t = expr_type::odd_pal;
- ret->leftson = parse(i, e);
- assert(i->t == token_type::STAR);
- ++i;
- assert(i->t == token_type::RBRACK);
- ++i;
- }
- return ret;
- }
- expr* parse_num(vector<token>::iterator& i, vector<token>::iterator e){
- assert(i->t == token_type::INT);
- expr *ret = new expr;
- ret->t = expr_type::repetition;
- ret->reps = i->x;
- ++i;
- assert(i->t == token_type::LPAR);
- ++i;
- ret->leftson = parse(i, e);
- assert(i->t == token_type::RPAR);
- ++i;
- return ret;
- }
- expr* parse(vector<token>::iterator& i, vector<token>::iterator e){
- expr* ret = new expr;
- if(i == e || i->t == token_type::RPAR || i->t == token_type::STAR || i->t == token_type::RBRACK)
- ret->t = nil;
- else if(i->t == token_type::INT)
- {
- ret->t = concat;
- ret->leftson = parse_num(i, e);
- ret->rightson = parse(i, e);
- }
- else if(i->t == token_type::LBRACK)
- {
- ret->t = concat;
- ret->leftson = parse_lbrack(i, e);
- ret->rightson = parse(i, e);
- }
- else if(i->t == token_type::STR){
- ret->t = concat;
- ret->leftson = new expr;
- ret->leftson->t = basic;
- ret->leftson->s = i->s;
- ++i;
- ret->rightson = parse(i, e);
- }
- return ret;
- }
- void evaluate(expr *e, string& s){
- ///cerr << e << ' ' << e->t << "L: " << e->leftson << "R: " << e->rightson << ' ' << "S: " << e->s << endl;
- assert(e);
- if(e->t == expr_type::concat){
- evaluate(e->leftson, s);
- evaluate(e->rightson, s);
- }
- else if(e->t == expr_type::odd_pal){
- string tmp;
- evaluate(e->leftson, tmp);
- s.append(tmp);
- tmp.pop_back();
- reverse(begin(tmp), end(tmp));
- s.append(tmp);
- }
- else if(e->t == expr_type::even_pal){
- string tmp;
- evaluate(e->leftson, tmp);
- s.append(tmp);
- reverse(begin(tmp), end(tmp));
- s.append(tmp);
- }
- else if(e->t == expr_type::repetition){
- string tmp;
- evaluate(e->leftson, tmp);
- for(int i = 0; i < e->reps; ++i)
- s.append(tmp);
- }
- else if(e->t == expr_type::basic){
- s.append(e->s);
- }
- else if(e->t == expr_type::nil){
- //
- }
- }
- int find_operation_count(expr *e){
- return e == nullptr ? 0 :
- find_operation_count(e->leftson) + find_operation_count(e->rightson) +
- (e->t == even_pal || e->t == odd_pal || e->t == repetition ? 1 : 0);
- }
- int main(){
- ifstream f("arh.in");
- ofstream g("arh.out");
- string s;
- f >> s;
- vector<token> tok = tokensise(s);
- auto it = begin(tok);
- ///for(auto x : tok)
- ///cerr << x.t << ' ' << x.s << ' ' << x.x << endl;
- expr *parse_tree = parse(it, end(tok));
- string ret;
- evaluate(parse_tree, ret);
- g << find_operation_count(parse_tree) << endl << ret << endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment