• xdoj-1298(模拟--简易SQL解释器)


    题目链接

    一 知识点:

      1  substr有2种用法:

          假设:string s = "0123456789";

         string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = "56789"

         string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = "567"

         2  find( x, p )   从p位置开始查找字符x的位置

         3  c++的split函数(自己搭建),利用strtok函数

           

    vector <string> split (const string& dem,const string & str) {// 将以dem为分隔的字符串分割
      vector <string> res;
      char *ss = new char[str.size() + 1];
      strcpy (ss, str.c_str());// string转字符串
      char*p = strtok(ss, dem);
      while (p) {
        string s = p;
        res.push_back(s);
        p = strtok(NULL, dem);
      }
      return res;
    }

    二  想法

     1 用split提取有用信息

     2 对于复合查询采用递归方式的查询

    三 代码

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 struct head {
      4   vector <string> col;
      5 };
      6 head h[10]; int cnt = 0;
      7 map <string, int> mapp;
      8 struct data {
      9   int id;// 对应的表头
     10   int num; // 有多少行 
     11   vector <string> c [100];  //存储每行的信息
     12   int a[10];  // 存储每行各元素所对应的列
     13 };
     14 data d[10];
     15 const char* dem = ", ";
     16 string sub (const string& str, int p, char last) {// 截取从p位置到以last结尾的字符串(不包括last)
     17   int p2 = str.find(last, p);// 从p位置开始查找last
     18   return str.substr(p, p2 - p);// 从p位置开始长度为(p2-p)的字符串
     19 }
     20 vector <string> split (const string & str) {// 将以dem为分隔的字符串分割
     21   vector <string> res;
     22   char *ss = new char[str.size() + 1];
     23   strcpy (ss, str.c_str());// string转字符串
     24   char*p = strtok(ss, dem);
     25   while (p) {
     26     string s = p;
     27     res.push_back(s);
     28     p = strtok(NULL, dem);
     29   }
     30   return res;
     31 }
     32 int find_c (const string& str, const vector <string>& res) {  //查找str 对应表头列的序号
     33   for (int i = 0; i < res.size(); i++)
     34     if (str == res[i])
     35       return i;
     36 }
     37 void m_print (const data& t) {
     38   for (int i = 1; i <= t.num; i++) {
     39     cout << t.c[i][0];
     40     for (int j = 1; j < t.c[i].size(); j++)
     41       cout << " " << t.c[i][j];
     42     cout << endl;  
     43   }
     44   cout << endl;
     45 }
     46 void creat (const string& s) {
     47   string ta = sub(s, 13, '(');// 截取表头
     48   int p = s.find('(');
     49   string s1 = sub(s, p + 1, ')'); // 截取各列信息
     50   mapp[ta] = ++cnt;// 各个表与id对应
     51   h[cnt].col = split(s1);
     52   return ;
     53 }
     54 void inser (const string&s) {
     55   // 表的信息
     56   string ta = sub(s, 12, '(');
     57 
     58   // 插入的列表
     59   int p1 = s.find('(');
     60   string s1 = sub(s, p1 + 1, ')');
     61   vector <string> r1 = split (s1);
     62 
     63    // 插入的信息
     64   int p2 = s.rfind('(');
     65   string s2 = sub(s, p2 + 1, ')');
     66   vector <string> r2 = split(s2);
     67 
     68   int id = mapp[ta]; int len = h[id].col.size()
     69   int k = ++d[id].num;
     70   for (int i = 0; i < len; i++) d[id].c[k].push_back("0");
     71 
     72   for (int i = 0; i < r1.size(); i++) { 
     73     int t = find_c(r1[i], h[id].col); // 找到要出插入列 在表头列表中的位置
     74     d[id].c[k][t] = r2[i];
     75   }
     76 }
     77 data se1 (const string& s) {// 无递归查询 返回一个集合
     78   data ans; ans.num = 0;
     79   // res 查询的列集合
     80   int p1 = s.rfind("from ");
     81   string s1 = s.substr (7, p1 - 8);
     82   vector <string> res = split(s1);
     83 
     84   string ta = sub (s, p1 + 5, ';');// 表头
     85   int id = mapp[ta];
     86   ans.num = d[id].num;
     87   ans.id = id;
     88 
     89   for (int i = 1; i <= ans.num; i++)// 每一行
     90     for (int j = 0; j < res.size(); j++) {// 每一列
     91       int k = find_c(res[j], h[id].col);
     92       ans.a[j] = k;
     93       ans.c[i].push_back(d[id].c[i][k]);
     94     }
     95   return ans;
     96 }
     97 data se2 (const string&s ) {//递归求解查询2
     98   data ans; ans.num = 0;
     99   // 得到前半部分t1集合(先忽略条件)
    100   int p1 = s.find ("where ");
    101   if (p1 == string::npos) return se1(s);
    102   string s1 = s.substr (0, p1);
    103   s1[p1 - 1] = ';';  data t1 = se1(s1);
    104 
    105   int p2 = s.find ("in ");
    106   string ss = s.substr(p1 + 6, p2 - 7 - p1);
    107   int k = find_c (ss, h[t1.id].col);// 得到指定列
    108 
    109   //得到条件集合t2
    110   string s2 = s.substr(p2 + 3);
    111   data t2 = se2(s2);
    112 
    113   //按条件筛选t1
    114   for (int i = 1; i <= t1.num; i++)
    115     for (int j = 1; j <= t2.num; j++)
    116       if (   d[t1.id].c[i][k]  == t2.c[j][0]) {
    117         ans.num++;
    118         ans.c[ans.num] = t1.c[i];
    119         break;
    120       }
    121   return ans;
    122 }
    123 int main ()
    124 {
    125   string s;
    126   while (getline(cin, s)) {
    127     if (s[0] == 'c')  creat (s);
    128     else if (s[0] == 'i') inser(s);
    129     else if (s[0] == 's' && s.find(" where ") == string::npos) {
    130       data t = se1(s);  m_print(t);
    131     }
    132     else  {
    133       data t = se2(s); m_print(t);
    134     }
    135   }
    136   return 0;
    137 }

    后记:

      缺点 :采用STL速度较慢.

      优点: 代码简洁易懂

       

    抓住青春的尾巴。。。
  • 相关阅读:
    Swift3.0 数组(Array)
    Swift3.0 UICollectionView简单使用
    Swift3.0 字符串(string)
    Swift3.0 元组 (tuples)
    Swift3.0 UICollectionView 删除,拖动
    Swift3.0 控制流
    Swift3.0 UITextView写反馈界面
    HashMap JDK1.8实现原理
    Volatile的详解
    阻塞队列之LinkedBlockingQueue
  • 原文地址:https://www.cnblogs.com/xidian-mao/p/9597088.html
Copyright © 2020-2023  润新知