题目链接

一 知识点:

  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() + ];
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 对于复合查询采用递归方式的查询

三 代码

 #include <bits/stdc++.h>
using namespace std;
struct head {
vector <string> col;
};
head h[]; int cnt = ;
map <string, int> mapp;
struct data {
int id;// 对应的表头
int num; // 有多少行
vector <string> c []; //存储每行的信息
int a[]; // 存储每行各元素所对应的列
};
data d[];
const char* dem = ", ";
string sub (const string& str, int p, char last) {// 截取从p位置到以last结尾的字符串(不包括last)
int p2 = str.find(last, p);// 从p位置开始查找last
return str.substr(p, p2 - p);// 从p位置开始长度为(p2-p)的字符串
}
vector <string> split (const string & str) {// 将以dem为分隔的字符串分割
vector <string> res;
char *ss = new char[str.size() + ];
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;
}
int find_c (const string& str, const vector <string>& res) { //查找str 对应表头列的序号
for (int i = ; i < res.size(); i++)
if (str == res[i])
return i;
}
void m_print (const data& t) {
for (int i = ; i <= t.num; i++) {
cout << t.c[i][];
for (int j = ; j < t.c[i].size(); j++)
cout << " " << t.c[i][j];
cout << endl;
}
cout << endl;
}
void creat (const string& s) {
string ta = sub(s, , '(');// 截取表头
int p = s.find('(');
string s1 = sub(s, p + , ')'); // 截取各列信息
mapp[ta] = ++cnt;// 各个表与id对应
h[cnt].col = split(s1);
return ;
}
void inser (const string&s) {
// 表的信息
string ta = sub(s, , '('); // 插入的列表
int p1 = s.find('(');
string s1 = sub(s, p1 + , ')');
vector <string> r1 = split (s1); // 插入的信息
int p2 = s.rfind('(');
string s2 = sub(s, p2 + , ')');
vector <string> r2 = split(s2); int id = mapp[ta]; int len = h[id].col.size()
int k = ++d[id].num;
for (int i = ; i < len; i++) d[id].c[k].push_back(""); for (int i = ; i < r1.size(); i++) {
int t = find_c(r1[i], h[id].col); // 找到要出插入列 在表头列表中的位置
d[id].c[k][t] = r2[i];
}
}
data se1 (const string& s) {// 无递归查询 返回一个集合
data ans; ans.num = ;
// res 查询的列集合
int p1 = s.rfind("from ");
string s1 = s.substr (, p1 - );
vector <string> res = split(s1); string ta = sub (s, p1 + , ';');// 表头
int id = mapp[ta];
ans.num = d[id].num;
ans.id = id; for (int i = ; i <= ans.num; i++)// 每一行
for (int j = ; j < res.size(); j++) {// 每一列
int k = find_c(res[j], h[id].col);
ans.a[j] = k;
ans.c[i].push_back(d[id].c[i][k]);
}
return ans;
}
data se2 (const string&s ) {//递归求解查询2
data ans; ans.num = ;
// 得到前半部分t1集合(先忽略条件)
int p1 = s.find ("where ");
if (p1 == string::npos) return se1(s);
string s1 = s.substr (, p1);
s1[p1 - ] = ';'; data t1 = se1(s1); int p2 = s.find ("in ");
string ss = s.substr(p1 + , p2 - - p1);
int k = find_c (ss, h[t1.id].col);// 得到指定列 //得到条件集合t2
string s2 = s.substr(p2 + );
data t2 = se2(s2); //按条件筛选t1
for (int i = ; i <= t1.num; i++)
for (int j = ; j <= t2.num; j++)
if ( d[t1.id].c[i][k] == t2.c[j][]) {
ans.num++;
ans.c[ans.num] = t1.c[i];
break;
}
return ans;
}
int main ()
{
string s;
while (getline(cin, s)) {
if (s[] == 'c') creat (s);
else if (s[] == 'i') inser(s);
else if (s[] == 's' && s.find(" where ") == string::npos) {
data t = se1(s); m_print(t);
}
else {
data t = se2(s); m_print(t);
}
}
return ;
}

后记:

缺点 :采用STL速度较慢.

优点: 代码简洁易懂

   

xdoj-1298(模拟--简易SQL解释器)的更多相关文章

  1. Python模拟简易版淘宝客服机器人

    对于用Python制作一个简易版的淘宝客服机器人,大概思路是:首先从数据库中用sql语句获取相关数据信息并将其封装成函数,然后定义机器问答的主体函数,对于问题的识别可以利用正则表达式来进行分析,结合现 ...

  2. 模拟实现SQL Server字段列显示的数据类型

    本文目录列表: 1.SQL Server表设计视图中的数据类型列展示效果 2.模拟实现类似的数据类型显示效果 3.测试效果 4.总结语 5.参考清单列表   1.SQL Server表设计视图中的数据 ...

  3. 模拟实现SQL Server中的datepart(week,date)的功能

    本文目录列表: 1.为什么要模拟实现datepart(week,date)的功能 2.具体实现思路 3.T-SQL代码实现逻辑 4.总结语 5.参考清单列表   1.为什么要模拟实现datepart( ...

  4. WindowsPhone模拟简易Toast弹出框

    Coding4Fun这个开源控件中有ToastPrompt这个弹出框组件,但是由于Coding4Fun太庞大,如果只用到ToastPrompt这个控件的话,整个引用不太值当的.于是自己写了一个差不多的 ...

  5. java模拟简易按键精灵

    很多小伙伴们都有过抢课的经历,有时候抢不到自己想上的课,只能盼望有人退选,可是很多时候别人退选了,但是很快又被别人抢走了,我们不可能时刻盯着电脑, 这时候如果有一个抢课的程序岂不是很棒.. 出于这个目 ...

  6. 简易SQL语句

    /*创建 模式 为用户 User1*/ CREATE SCHEMA test authorization User1; CREATE SCHEMA test USER User1; CREATE TA ...

  7. linux c++模拟简易网络爬虫

    /* * To change this license header, choose License Headers in Project Properties. * To change this t ...

  8. .NET面试题系列[14] - LINQ to SQL与IQueryable

    .NET面试题系列目录 名言警句 "理解IQueryable的最简单方式就是,把它看作一个查询,在执行的时候,将会生成结果序列." - Jon Skeet LINQ to Obje ...

  9. SQL Server Profiler

    一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问 ...

随机推荐

  1. SpringBoot 配置文件存放位置及读取顺序

    SpringBoot配置文件可以使用yml格式和properties格式 分别的默认命名为:application.yml.application.properties 存放目录 SpringBoot ...

  2. mybatis标签之——<trim>及 <foreach collection>

    https://www.cnblogs.com/zjfjava/p/8882614.html trim标记是一个格式化的标记,主要用于拼接sql的条件语句(前缀或后缀的添加或忽略),可以完成set或者 ...

  3. Struts 2 初步入门(三)

    接Struts 2初步入门(二) 若想用多个通配符设定访问: <struts> <package name="default" namespace="/ ...

  4. radio选择

    input标签radio单选 <tr> <th style="font-weight: bolder;text-align: right;width:18%" & ...

  5. js原生回到顶部

    <!DOCTYPE html><html><head> <meta content="测试demo" name="Keyword ...

  6. laravel获取当前的url以及当前的基础域名方法汇总

    原文地址:https://phpartisan.cn/news/58.html 来源于:laravel获取当前的url以及当前的基础域名方法汇总 - Laravel学习网 laravel中我们常常需要 ...

  7. Win10系列:UWP界面布局基础5

    (2)编写后台代码访问资源 下面通过一个例子来演示如何编写后台代码引用资源.新建一个Windows应用商店的空白应用程序项目,将其命名为AccessResourceApplication,打开项目下的 ...

  8. Java数值类型之间转换

    Java之间的数值转换如图所示,实心箭头代表无数据丢失,虚线箭头代表可能丢失 例如:123456789是一个大的整数,包含的位数比float类型能够表达的位数多,但这个数转换为float类型时,将会得 ...

  9. 什么是Java优先级队列(Priority Queue)?

    PriorityQueue是一个基于优先级堆的无界队列.它的元素是按照自然顺序排序的.在创建元素的时候,我们给它一个一个负责排序的比较器.PriorityQueue不允许null值,因为 它们没有自然 ...

  10. do while

    do while结构的基本原理和while结构是基本相同的,但是它保证循环体至少被执行一次.因为它是先执行代码,后判断条件,如果条件为真,继续循环.