牛客寒假算法基础集训营3

本文介绍了SQL中的GROUP BY语句用于对数据库表进行分组聚合的操作,通过实例展示了如何根据一个或多个列进行分组,并统计每组的数据数量。文章还提供了代码实现,解释了如何处理和统计GROUP BY查询的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

智乃最近在学习数据库的查询语言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;

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
1 2 1

说明

 

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

例如

3

2 1 1

则也能得到正确的结果。

思路:

把每一排需要标记的类型的序号

合在一起构成字符串

对于每排进行遍历

每次对该排的字符串类型的数量进行++

输出的种类数即为按照题目要求能分成的类别

然后依次输出之前统计的

不同种类拼接字符串的数量

这样即为正解

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,a[1010][1010];
string s[1010];
map<string,int>mp,p;
string g;
vector<int> f;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
        cin>>s[i],p[s[i]]=i;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    getchar();
    getline(cin,g);
    int o=36;
    for(int i=36;i<=g.length();i++)
        if(g[i]==','||g[i]==';')
            f.push_back(p[g.substr(o,i-o)]),o=i+1;//统计需要辨别的字符段
    for(int i=1;i<=n;i++)
    {
        string s;
        for(int j=0;j<f.size();j++)
        {
            s=s+to_string(a[i][f[j]]);//对需要辨别的字符段相加,构成新的字符
        }
        mp[s]++;//对于组成的数组进行++(起到统计相同数组的作用)
    }
    cout<<mp.size()<<endl;
    for(auto x:mp)
        cout<<x.second<<" ";//输出mp中每个不同组成类型数组的个数
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值