描述:
“阿里代码库有几亿行代码,但其中有很多功能重复的代码,比如单单快排就被重写了几百遍。请设计一个程序,能够将代码库中所有功能重复的代码找出。各位大佬有啥想法,我当时就懵了,然后就挂了。。。”
这里我们把问题简化一下:首先假设两个功能模块如果接受同样的输入,总是给出同样的输出,则它们就是功能重复的;其次我们把每个模块的输出都简化为一个整数(在 int 范围内)。于是我们可以设计一系列输入,检查所有功能模块的对应输出,从而查出功能重复的代码。你的任务就是设计并实现这个简化问题的解决方案。
输入:
输入在第一行中给出 2 个正整数,依次为 N(≤104)和 M(≤102 ),对应功能模块的个数和系列测试输入的个数。
随后 N 行,每行给出一个功能模块的 M 个对应输出,数字间以空格分隔。
输出:
首先在第一行输出不同功能的个数 K。随后 K 行,每行给出具有这个功能的模块的个数,以及这个功能的对应输出。数字间以 1 个空格分隔,行首尾不得有多余空格。输出首先按模块个数非递增顺序,如果有并列,则按输出序列的递增序给出。
注:所谓数列 { A 1, …, A M} 比 { B 1 , …, B M} 大,是指存在 1≤i<M,使得 A 1=B 1,…,A i=B i成立,且 A i+1>B i+1。
思路:
用 map 来计数,放入结构体中进行排序
代码一:用结构体数组处理
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; typedef long long ll; const ll maxx = 1e18; const int N = 1e6+100; const int p = 1e4+10; const double eps = 1e-8; int n,m,key; map<vector<int>,int>mp;//map 来计数 struct node{ vector<int>ve; int cnt; }a[p];//结构体来排序 int cnts;//记录结构体中数据个数 bool cmp(node a,node b) { return a.cnt>b.cnt||(a.cnt==b.cnt&&a.ve<b.ve); }//排序规则 int main() { cin>>n>>m; for(int i=1;i<=n;i++) { vector<int>ve; for(int j=1;j<=m;j++) { cin>>key; ve.push_back(key); } mp[ve]++; }//存入map int len=mp.size();//记录总数 k cout<<len<<endl; for(auto k : mp) { a[++cnts].ve=k.first; a[cnts].cnt=k.second; }//存入结构体 sort(a+1,a+1+cnts,cmp);//进行排序 for(int i=1;i<=cnts;i++) { cout<<a[i].cnt<<" "; int lens=a[i].ve.size(); for(int j=0;j<lens;j++) { if(j==lens-1) cout<<a[i].ve[j]<<endl; else cout<<a[i].ve[j]<<" "; }//全部输出,注意格式 } }
代码二:用动态数组处理结构体
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; typedef long long ll; const ll maxx = 1e18; const int N = 1e6+100; const int p = 1e4+10; const double eps = 1e-8; int n,m,key; map<vector<int>,int>mp;//map 来计数 struct node{ vector<int>ve; int cnt; }node1;//结构体来排序 vector<node>vec; int cnts;//记录结构体中数据个数 bool cmp(node a,node b) { return a.cnt>b.cnt||(a.cnt==b.cnt&&a.ve<b.ve); }//排序规则 int main() { cin>>n>>m; for(int i=1;i<=n;i++) { vector<int>ve; for(int j=1;j<=m;j++) { cin>>key; ve.push_back(key); } mp[ve]++; }//存入map int len=mp.size();//记录总数 k cout<<len<<endl; for(auto k : mp) { node1.cnt=k.second; node1.ve=k.first; vec.push_back(node1); }//存入结构体 sort(vec.begin(),vec.end(),cmp);//进行排序 for(auto k : vec) { cout<<k.cnt<<" "; int len=k.ve.size(); for(int i=0;i<len;i++) { if(i!=len-1) cout<<k.ve[i]<<" "; else cout<<k.ve[i]<<endl; } } }
反思与总结:
1.vector默认能比较大小,学到了
2.结构体处理可以用结构体数组和动态数组两种方式处理,当然vector处理更好,多种类型数据排序就去想结构体;
3.注意不同处理方法快排写法不同