BNUOJ 51639 Simple Database(大模拟)

题意:

$模拟sql语句的执行过程,具体见题面$,点击

分析:

$创建表,删除表,插入表都没啥说的$
$就是删除的条件可以省略,以及SET WHERE后面是有多个条件的$
$然后没啥照着模拟就好了,咋样好写咋来$
$弱智的我表示加上调试语句写了9.4k$
$时间复杂度自己估算能跑得过就好了,反正vector我当时算了是没问题的$

代码:

//
//  Created by TaoSama on 2016-04-23
//  Copyright (c) 2016 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:102400000,102400000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#include <sstream>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

void RE() {
    printf("%d\n", *((int*)0));
}

struct Table {
    string name;
    vector<string> key;
    vector<vector<string> > content;
    Table() {}
    Table(string name, vector<string> key): name(name), key(key) {}

    void add(vector<string> row) {
        if(key.size() != row.size()) {
            cout << "add illegal row\n";
            RE();
        }
        content.push_back(row);
    }

    void del(vector<pair<string, string> >& conditions) {
        vector<vector<string> >::iterator iter = content.begin();
        for(; iter != content.end();) { //row
            bool ok = true;
            for(int j = 0; j < iter->size(); ++j) { //col
                for(int k = 0; k < conditions.size(); ++k) { //conditions
                    if(key[j] == conditions[k].first) {
                        if((*iter)[j] != conditions[k].second) {
                            ok = false;
                            break;
                        }
                    }
                }
                if(!ok) break;
            }
            if(ok) iter = content.erase(iter);
            else ++iter;
        }
    }

    void update(vector<pair<string, string> >& sets,
                vector<pair<string, string> >& conditions) {
        for(int i = 0; i < content.size(); ++i) { //row
            bool ok = true;
            for(int j = 0; j < content[i].size(); ++j) { //col
                for(int k = 0; k < conditions.size(); ++k) {
                    if(key[j] == conditions[k].first) {
                        if(content[i][j] != conditions[k].second) {
                            ok = false;
                            break;
                        }
                    }
                }
                if(!ok) break;
            }
            if(!ok) continue;
            //update
            for(int j = 0; j < content[i].size(); ++j) {
                for(int k = 0; k < sets.size(); ++k) {
                    if(key[j] == sets[k].first)
                        content[i][j] = sets[k].second;
                }
            }
        }
    }

    vector<int> select(vector<pair<string, string> >& conditions) {
        vector<int> choose;
        for(int i = 0; i < content.size(); ++i) { //row
            bool ok = true;
            for(int j = 0; j < content[i].size(); ++j) { //col
                for(int k = 0; k < conditions.size(); ++k) {
                    if(key[j] == conditions[k].first) {
                        if(content[i][j] != conditions[k].second) {
                            ok = false;
                            break;
                        }
                    }
                }
                if(!ok) break;
            }
            if(ok) choose.push_back(i);
        }
        return choose;
    }
};
vector<Table> db;

#ifdef LOCAL
void see1(vector<string>& v) {
    for(auto s : v) cout << s << ' '; cout << endl;
}

void seedb() {
    cout << endl << string(20, '*') << endl;
    for(auto table : db) {
        cout << "name: " << table.name << endl;
        for(auto key : table.key) cout << key << ' '; cout << endl;
        for(auto vs : table.content) {
            for(auto s : vs) {
                cout << s << ' ';
            }
            cout << endl;
        }
    }
    cout << string(20, '*') << endl << endl;
}

void seeCondition(vector<pair<string, string> >& conditions) {
    for(auto p : conditions)
        cout << p.first << "=" << p.second << endl;
    cout << endl;
}
#endif // LOCAL

int findTable(string& name) {
    for(int i = 0; i < db.size(); ++i) {
        Table& table = db[i];
        if(name == table.name) return i;
    }
    return -1;
}

bool isSymbol(char c) {
    if(isalnum(c) || c == '_') return false;
    return true;
}

bool strip(string& s) {
    while(s.size() && isSymbol(s[0])) s.erase(0, 1);
    while(s.size() && isSymbol(s[s.size() - 1])) s.erase(s.size() - 1, 1);
}

void split(string& s, vector<string>& vs) {
    stringstream ss(s);
    string col;
    while(ss >> col) {
        strip(col);
        vs.push_back(col);
    }
}

void create(string& s) {
    vector<string> vs;
    split(s, vs);
//    see1(vs);

    if(~findTable(vs[0])) {cout << "error\n"; return;}
    db.push_back(Table(vs[0], vector<string>(vs.begin() + 1, vs.end())));
}

void drop(string& s) {
    int wh = findTable(s);
    if(wh == -1) {cout << "error\n"; return;}
    db.erase(db.begin() + wh);
}

void insert(string& s) {
    vector<string> vs;
    split(s, vs);
//    see1(vs);

    int wh = findTable(vs[0]);
    if(wh == -1) {cout << "error\n"; return;}
    db[wh].add(vector<string>(vs.begin() + 1, vs.end()));
}

void split(string& s, string& name, vector<pair<string, string> >& sets,
           vector<pair<string, string> >& conditions) {
    int white = s.find(' ');
    name = s.substr(0, white);
    s = s.substr(white + 1);

    size_t SET = s.find("SET");
    size_t WHERE = s.find("WHERE");
    if(SET != string::npos) {
        SET += 3;
        string setString = s.substr(SET, WHERE - SET);
        stringstream ss(setString);
        string key, value;
        while(ss >> key >> value >> value) {
            strip(key); strip(value);
            sets.push_back(make_pair(key, value));
        }
    }

    if(WHERE != string::npos) {
        WHERE += 5;
        string conditionString = s.substr(WHERE);
        stringstream ss(conditionString);
        string key, value;
        while(ss >> key >> value >> value) {
            strip(key); strip(value);
            conditions.push_back(make_pair(key, value));
        }
    }
}

bool checkKey(int wh, vector<pair<string, string> >& sets,
              vector<pair<string, string> >& conditions) {
    Table& table = db[wh];
    for(int i = 0; i < sets.size(); ++i) {
        bool have = false;
        for(int j = 0; j < table.key.size(); ++j) {
            if(sets[i].first == table.key[j]) {
                have = true;
                break;
            }
        }
        if(!have) return false;
    }
    for(int i = 0; i < conditions.size(); ++i) {
        bool have = false;
        for(int j = 0; j < table.key.size(); ++j) {
            if(conditions[i].first == table.key[j]) {
                have = true;
                break;
            }
        }
        if(!have) return false;
    }
    return true;
}

void del(string& s) {
    string name;
    vector<pair<string, string> > sets, conditions;
    split(s, name, sets, conditions);
    int wh = findTable(name);
    if(wh == -1) {cout << "error\n"; return;}

//    seeCondition(sets); seeCondition(conditions);

    if(!conditions.size()) db[wh].content.clear();
    else {
        if(!checkKey(wh, sets, conditions)) {cout << "error\n"; return;}
        db[wh].del(conditions);
    }
}

void update(string& s) {
    string name;
    vector<pair<string, string> > sets, conditions;
    split(s, name, sets, conditions);
    int wh = findTable(name);
    if(wh == -1) {cout << "error\n"; return;}
    if(!checkKey(wh, sets, conditions)) {cout << "error\n"; return;}

//  seeCondition(sets); seeCondition(conditions);

    db[wh].update(sets, conditions);
}

void select(string& s) {
    string name;
    vector<pair<string, string> > sets, conditions;
    split(s, name, sets, conditions);
    int wh = findTable(name);
    if(wh == -1) {cout << "error\n"; return;}
    if(!checkKey(wh, sets, conditions)) {cout << "error\n"; return;}

//    puts("select");
//    seeCondition(conditions);

    Table& table = db[wh];
    vector<int> choose = table.select(conditions);
    for(int i = 0; i < table.key.size(); ++i) {
        if(i) cout << ' ';
        cout << table.key[i];
    }
    cout << '\n';
    for(int i = 0; i < choose.size(); ++i) {
        vector<string>& v = table.content[choose[i]];
        for(int j = 0; j < v.size(); ++j) {
            if(j) cout << ' ';
            cout << v[j];
        }
        cout << '\n';
    }
}

int main() {
#ifdef LOCAL
    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif

    int t; cin >> t;
    while(t--) {
        int q; cin >> q; cin.get();
        static int kase = 0;
        cout << "Case #" << ++kase << ":\n";

        db.clear();
        while(q--) {
            string s;  getline(cin, s);
            int white = s.find(' ');
            string cmd = s.substr(0, white);
            string lft = s.substr(white + 1);

            if(cmd == "CREATE") create(lft);
            else if(cmd == "DROP") drop(lft);
            else if(cmd == "INSERT") insert(lft);
            else if(cmd == "DELETE") del(lft);
            else if(cmd == "UPDATE") update(lft);
            else select(lft);

//            cout << q << endl; seedb();
        }
    }
    return 0;
}