智乃的数据库

题目链接

智乃最近在学习数据库的查询语言SQL。SQL (Structured Query Language:结构化查询语言) 是用于管理关系数据库管理系统(RDBMS)。 SQL 的范围包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制。

使用SQL,可以灵活的对数据库表进行操作,在数据库的查询语句中有"GROUP BY"这样一种关键字。

GROUP BY 语句用于结合聚合函数,根据一个或多个列对结果集进行分组。

例如数据库中储存了这样一个数据库表Table,执行带有"GROUP BY"关键字的查询语句。

idnameval
1chino1
2chino2
3kokoa3
SELECT COUNT(*) FROM Table GROUP BY name;

SQL语句中COUNT表示聚合后每一个组中有多少条数据。

当执行上述的SQL查询语句后,其返回的结果如下

2
2 1

第一行的2表示按照name字段进行分组聚合,一共可以分出2组。

第二行的两个整数表示每组中各有多少条数据。

当然了,"GROUP BY"关键字是可以选中多个列进行分组聚合的,只需要把这些字段用逗号隔开即可。

SELECT COUNT(*) FROM Table GROUP BY name,val;

例如这样的SQL查询语句,执行后返回的结果如下

3
1 1 1

现在智乃把这张数据库表导出给你,请你执行一个SELECT COUNT(*) FROM Table GROUP BY ...;的查询语句,请你把查询的结果告诉智乃。

为了简化问题,我们假设数据库的表由NNN条记录以及MMM个字段组成,且这些字段的类型均为int类型。

输入描述:

 

第一行输入两个正整数N,M(1≤N,M≤1000){N,M(1\leq N,M\leq1000)}N,M(1≤N,M≤1000),表示数据库表中有NNN条记录以及MMM个字段。

接下来一行输入MMM个字符串Si(1≤∣Si∣≤50)S_i (1\leq|S_i|\leq50)Si​(1≤∣Si​∣≤50)表示每个字段的名称。

接下来NNN行,每行MMM列,输入一个二维表格datai,j(0≤datai,j≤109)data_{i,j} (0\leq data_{i,j} \leq 10^9)datai,j​(0≤datai,j​≤109)表示数据库表中第i{i}i条记录的第j{j}j个字段的值。

接下来输入一行一个字符串SQL(1≤∣SQL∣≤5×104)SQL(1\leq |SQL|\leq5\times10^4)SQL(1≤∣SQL∣≤5×104),表示查询语句,查询语句的格式为"SELECT    COUNT(∗)    FROM    Table    GROUP    BY    ...;""SELECT\;\;COUNT(*)\;\;FROM\;\;Table\;\;GROUP\;\;BY\;\;...; ""SELECTCOUNT(∗)FROMTableGROUPBY...;"。

其中"...""...""..."是若干个字段名称,保证是之前输入的MMM个字段中的某些字段,且这若干个字段互不相同,字段与字段之间用一个逗号隔开。

输出描述:

 

第一行输出一个整数KKK表示聚合后组的数目。

接下来一行输出KKK个整数,表示每组中聚合的记录数目,整数与整数之间用空格隔开。

你可以按照你喜欢的顺序输出答案,裁判程序将忽略输出顺序的影响。

示例1

输入

4 3
id name val
1 1 2
1 1 3
1 2 1
2 2 2
SELECT COUNT(*) FROM Table GROUP BY name,id;

输出

3
1 2 1

说明

 

你可以按照自己喜欢的顺序输出

例如

3

2 1 1

则也能得到正确的结果。

思路:字符串的判重记录个数,或者数据“串”的判重与记录个数,直接用map存数据(ps:数据量不到1e9).我们定义map<string,int>类来记录字符串对应的下标与位置;map<vector<int>,int>来记录数据串是否相同。我们需要一行一行来记录,因为是行与行之间来比较的。我们只需要记录用到哪几列,一行一行读就行,将一行一行的数据存在vector中,再用map<vector>判重记录即可,这样输出即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long
const int mod=1e9+7;

const int N=1010;
map<string,int>mp;
int a[N][N];
string s,ss;
vector<int>v,v1;
map<vector<int>,int>mp2;

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        string b;
        cin>>b;
        mp[b]=i;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    cin>>s;cin>>s;cin>>s;cin>>s;cin>>s;cin>>s;cin>>s;
    for(int i=0;i<=s.size();i++)
    {
        if(s[i]==','||s[i]==';')
        {
            v.push_back(mp[ss]);
            ss="";
        }
        else
        {
            ss+=s[i];
        }
    }
    for(int i=1;i<=n;i++)
    {
        v1.clear();
        for(auto x:v)
        {
            v1.push_back(a[i][x]);
        }
        mp2[v1]++;
    }
    cout<<mp2.size()<<endl;
    for(auto [i,j]:mp2)
    {
        cout<<j<<" ";
    }
    cout<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值