题解:P10788 [入门赛 #25] sql
分析
模拟。我们分成三步处理。
存表
我们用
输入
对于表的信息,直接输入即可。
对于查询,我们一个一个读入每个部分。当遇到 select 等读入内容的声明时,我们打标记来记录接下来要读入的内容是什么。在读入信息时要处理一遍,将信息存储下来。
处理
先将要输出的表头在表中的位置记录下来,再暴力查找输出即可。
具体的过程和注释请查看代码。
AC Code
#include<bits/stdc++.h>
using namespace std;
const int N=1005,M=15,X=105;
string table_name[N],table[M][X][M];
//table数组存表,第一维为第几个表,第二维为行,第三维为列
int n,m,x[M],y[M];
int main(){
ios::sync_with_stdio(NULL);
cin.tie(NULL);cout.tie(NULL);
//输入表的信息
cin>>n;
for(int i=1;i<=n;i++){
cin>>table_name[i];
cin>>x[i]>>y[i];
for(int j=1;j<=y[i];j++)
cin>>table[i][1][j];
for(int j=2;j<=x[i];j++)
for(int k=1;k<=y[i];k++)
cin>>table[i][j][k];
}
cin>>m;
while(m--){
string s,columns[M],header,qx;
//qx、columns、header分别对应题目中的x、columns、header
int stmp=0,cnt=1,ftmp=0,wtmp=0,ntmp=0;
//stmp、ftmp、wtmp都为标记,记录当前读入的内容是什么
//cnt为columns表头的个数,ntmp为当前查询的表是第几个
while(cin>>s){
int len=s.size();
//将表头分开存到columns内
if(stmp){
for(int i=0;i<len;i++){
if(s[i]==','){
cnt++;
continue;
}
columns[cnt]+=s[i];
}
//记得要清空标记!
stmp=0;
continue;
}
//查找当前查询的表是哪个
if(ftmp){
for(int i=1;i<=n;i++)
if(table_name[i]==s){
ntmp=i;
break;
}
ftmp=0;
continue;
}
//将要查询的表头和条件存起来
if(wtmp){
int tmp=0;
for(int i=0;i<len;i++){
if(s[i]=='='){
tmp=1;
continue;
}
//遇到'='前是表头,后是条件
if(!tmp)header+=s[i];
else qx+=s[i];
}
wtmp=0;
break;
}
//打标记记录
if(s=="select"){
stmp=1;
continue;
}
if(s=="from"){
ftmp=1;
continue;
}
if(s=="where"){
wtmp=1;
continue;
}
}
int wz[M]={0};
//查找columns在表中的位置,存在qu中
for(int i=1;i<=cnt;i++)
for(int j=1;j<=y[ntmp];j++)
if(columns[i]==table[ntmp][1][j])
wz[i]=j;
for(int i=1;i<=y[ntmp];i++)//遍历列
if(header==table[ntmp][1][i]){//找到符合的表头
for(int j=2;j<=x[ntmp];j++)//遍历行
if(table[ntmp][j][i]==qx){//找到符合的条件
//输出
for(int k=1;k<=cnt;k++)
cout<<table[ntmp][j][wz[k]]<<" ";
cout<<"\n";
}
break;
}
}
return 0;
}
蒟蒻只会暴力,大佬轻喷。