上图转自新浪微博:“阿里代码库有几亿行代码,但其中有很多功能重复的代码,比如单单快排就被重写了几百遍。请设计一个程序,能够将代码库中所有功能重复的代码找出。各位大佬有啥想法,我当时就懵了,然后就挂了。。。”
这里我们把问题简化一下:首先假设两个功能模块如果接受同样的输入,总是给出同样的输出,则它们就是功能重复的;其次我们把每个模块的输出都简化为一个整数(在 int 范围内)。于是我们可以设计一系列输入,检查所有功能模块的对应输出,从而查出功能重复的代码。你的任务就是设计并实现这个简化问题的解决方案。
输入格式:
输出格式:
输入样例:
7 3 35 28 74 -1 -1 22 28 74 35 -1 -1 22 11 66 0 35 28 74 35 28 74
输出样例:
4 3 35 28 74 2 -1 -1 22 1 11 66 0 1 28 74 35
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(pair<vector<int>, int>& a, pair<vector<int>, int>& b)
{
if (a.second != b.second) {
return a.second > b.second;
}
else { //此处vector储存的数据类型为基本数据类型int,可以直接比较大小
return a.first < b.first; //哪怕不是基本数据类型,也可以自行编写新的仿函数进行使用
}
}
int main()
{
int n, m, temp;
cin >> n >> m;
map<vector<int>, int> mode; //map容器:储存模块功能输出值,模块个数
vector<int> output; //vector容器:储存模块功能输出值
while (n--) {
for (int j = 0; j < m; j++) {
cin >> temp;
output.push_back(temp); //获取模块功能输出值
}
mode[output]++; //模块输出相同,个数+1
output.clear(); //清空容器
}
//map容器只能对key值(模块功能输出值)排序,
//而我们排序需要先考虑“模块个数”再考虑“模块功能输出值”
vector<pair<vector<int>, int>> res(mode.begin(), mode.end());
sort(res.begin(), res.end(), cmp);
cout << res.size() << endl;
for (vector<pair<vector<int>, int>>::iterator it = res.begin(); it != res.end(); it++) {
cout << it->second;
for (int i = 0; i < m; i++) {
cout << " " << it->first[i];
}
cout << endl;
}
return 0;
}
注意事项:
放一下测试点4和6均运行超时的代码,仅供参考:
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> using namespace std; int m; struct node { int key; int num[100]; }mode[10000]; bool cmp(node a, node b) { if (a.key == b.key) { for (int i = 0; i < m; i++) { if (a.num[i] < b.num[i]) return 1; } return 0; } return a.key > b.key; } int main() { int n, count = 1; cin >> n >> m; node temp; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) //用临时变量储存数据 cin >> temp.num[j]; if (i == 0) { //第一个不同模块特别处理 temp.key = 1; mode[0] = temp; continue; } int status = 0;//检查是否先前出现过该模块,1为已找到相同模块 for (int j = 0; j < count && status == 0; j++) { for (int k = 0; k < m; k++) { if (temp.num[k] != mode[j].num[k]) break; if (k == m - 1) { mode[j].key++; status = 1; break; } } } if (status == 0)//检查结束仍未发现相同模块,则发现新的不同模块 { temp.key = 1; mode[count++] = temp; } } sort(mode, mode + count, cmp); cout << count << endl; for (int i = 0; i < count; i++) { printf("%d", mode[i].key); for (int j = 0; j < m; j++) { printf(" %d", mode[i].num[j]); } printf("\n"); } return 0; }
参考文章:L2-039 清点代码库 作者:_hys
特别感谢上述作者提供的内容!
如有问题,欢迎提出。