题解:P10788 [入门赛 #25] sql

· · 题解

分析

模拟。我们分成三步处理。

存表

我们用 table\_name 数组存储表的名称,table 存储表的内容(包括表头),xy 数组分别存储每个表的行数和列数。

输入

对于表的信息,直接输入即可。

对于查询,我们一个一个读入每个部分。当遇到 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;
}

蒟蒻只会暴力,大佬轻喷。