题目链接

一 知识点:

  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. rexec/rlogin/rsh介绍

    服务 是否需要密码 是否明文 功能 端口 rexec 是 是 远程执行命令 512 rlogin 是 是 远程登录得到shell 513 rsh 是 是 可远程执行命令,也可远程登录得到shell 5 ...

  2. anglar cli的 rxjs_1.of is not a function

    按照官网敲例子遇到 rxjs_1.of is not a function import { Observable,of } from 'rxjs'; 改为 import { Observable} ...

  3. Linux第六周作业

    一 实验过程 1 先进入LinuxKernel环境下,更新menu代码到最新版,用到的命令为rm menu -rf //强制删除当前menu,git clone http://git.shiyanlo ...

  4. Java Web(九) JDBC及数据库连接池及DBCP,c3p0,dbutils的使用

    DBCP.C3P0.DBUtils的jar包和配置文件(百度云盘):点我下载 JDBC JDBC(Java 数据库连接,Java Database Connectify)是标准的Java访问数据库的A ...

  5. datetime.strptime格式转换报错ValueError

    今天遇到一个报错:ValueError: time data '2018-10-10(Wednesday) AM0:50' does not match format '%Y-%m-%d(%A) %p ...

  6. Resharper插件如何启用原VS的智能提示

    第一步:vs2015选择工具—>选项—>文本编辑器—>C#—>常规—>语句结束,勾选自动列出成员,如下图: 第二步: 关闭Resharper智能提示,并设置为Visual ...

  7. 自己写了一个解析json为table的工具类

    还需要完善的包括,css的封装,触发事件,数据的获得处理: <!DOCTYPE html> <html> <head> <meta charset=" ...

  8. 第三组 通信一班 030 IPv6 RIPng (PT)

    实验拓扑 地址规划 设备 接口 IPV6  地址/掩码 PC0 / 2001:DB8:30:2:201:42FF:FE8A:7688/64 PC1 / 2001:DB8:30:1:230:A3FF:F ...

  9. SQL-24 获取所有非manager员工当前的薪水情况,给出dept_no、emp_no以及salary ,当前表示to_date='9999-01-01'

    题目描述 获取所有非manager员工当前的薪水情况,给出dept_no.emp_no以及salary ,当前表示to_date='9999-01-01'CREATE TABLE `dept_emp` ...

  10. 201621123001 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 一个进程可以同时运行多个不同线程,不同的线程执行不同的任务 Java线程是通过java.lang包中定义的Thre ...