欢迎大家!
我是奥列格专业化:C ++ / C / OS内核/驱动程序/硬件/网络/嵌入式。我在国外生活和工作了大约一年半。现在在芬兰,在那之前是波兰。他们告诉我在我之前有兴趣搬到这两个国家的特殊性,请写下来,我会回答问题。关于这些国家生活的文章也很多。但是有一天,我将以免费论文的形式表达我对两者的印象。
现在,我想谈谈我花了半天时间解决的问题,尽管这不值得。有趣的是,我在面试中解决了一些类似的问题。我在挖掘我的一个家庭项目时遇到了她。
因此,给定一定数量的不同大小的整数集。您需要找到除一组以外的所有组中的数字。还需要元素缺少的集合的索引。
假设有集合{1、2、3},{3、0、4},{5}。在此人工示例中,出现在第零组和第一组中而在第二组中不存在的元素{3}声称是发现。也可以将其写为集合{3,2}。从字面上看,该记录的解释如下:集合2中不存在值3。另一个条件:只有1到64之间的正整数参与其中,每个集合的元素都是唯一的。
从根本上讲,这是经典面试问题的一种概括。后者的公式如下:在程序的某个块的输入处接收数字,因此有必要切断重复项。使用STL unordered_set原语可以轻松解决该问题。很好,因为它具有O(1)-短数字序列的恒定搜索时间。在有限任务的框架内,它本身的味道和颜色非常令人愉悦。此外,当向它添加副本时,它根本不会添加它。在这种情况下,也不必检查返回值。也就是说,我们节省了三行代码,它们仍然包含在模板的实现中。但是,由于我项目中的数字范围有限,因此完全可以不用它。是的,如果您扩展数字范围,则必须使用unordered_set或类似的东西。
为简单起见,让我们将集合的数量设置为等于3。该集合存储在向量或STL模板向量<vector>中。结果是一组成对的非负数向量<pair <int,int >>。在一对中,首先是元素本身,第二是元素集的索引,而元素索引则不在。
void PrepareData(const vector<vector<int> >& src, vector<pair<int, int> >& res)
{
vector<pair<int, int> > data(MAX); //
for(unsigned i(0); i < src.size(); ++i)
{
const auto& rf(src[i]);
for(unsigned j(0); j < rf.size(); ++j)
{
ASSERT(((0 < rf[j]) && (MAX > rf[j])) && "!!! An invalid data !!!");
++data[rf[j]].first; //
data[rf[j]].second += i; //
}
}
auto fs(((src.size() - 1) * src.size()) >> 1); //
for(unsigned i(0); i < data.size(); ++i) //
{
if(data[i].first == src.size() - 1) //
{
pair<int, int> cur{i, 0}; //
cur.second = fs - data[i].second; // ,
res.push_back(cur);
}
}
}
1)
2) . . , .
3) data . , , ,
4) , (a[1] + a[n]) * n / 2
5) , ,
6) , ,
就这样,半天的折磨。该代码并不假装精美。所希望的只是提出一个想法或解决此类问题的方法。特别感谢Ilyaata,谁建议我注意算法的优化性。
链接到代码https://yadi.sk/d/F2dLt6v_uvjKdQ