O(N log N)
这是复杂性的一个工作示例。它首先对数据进行排序,然后遍历每个元素并通过查找第一个不匹配来计算出现次数,然后将当前元素的计数总和存储在结果向量中。请注意,您的初始数组中的计数也可以不同于 1。该代码无需指定特定的比较函数即可工作,因为std::array
已经有一个 lexicographic operator<
。
下面的代码使用了可能无法在您的编译器上运行的 C++11 功能(自动、lambda)。您也可以使用 initalizer 列表在一个语句中初始化向量,但是使用一对 int 和数组的嵌套向量,我对需要编写多少个大括号有点困惑 :-)
#include <algorithm>
#include <array>
#include <iostream>
#include <utility>
#include <vector>
typedef std::pair<int, std::array<char, 3> > Element;
std::vector< Element > v;
std::vector< Element > result;
int main()
{
v.push_back( Element(1, std::array<char, 3>{{'a', 'b', 'c'}}) );
v.push_back( Element(2, std::array<char, 3>{{'a', 'b', 'c'}}) );
v.push_back( Element(1, std::array<char, 3>{{'c', 'd', 'e'}}) );
v.push_back( Element(1, std::array<char, 3>{{'b', 'c', 'd'}}) );
v.push_back( Element(3, std::array<char, 3>{{'b', 'c', 'd'}}) );
// O(N log(N) ) complexity
std::sort(v.begin(), v.end(), [](Element const& e1, Element const& e2){
// compare the array part of the pair<int, array>
return e1.second < e2.second;
});
// O(N) complexity
for (auto it = v.begin(); it != v.end();) {
// find next element
auto last = std::find_if(it, v.end(), [=](Element const& elem){
return it->second != elem.second;
});
// accumulate the counts
auto count = std::accumulate(it, last, 0, [](int sub, Element const& elem) {
return sub + elem.first;
});
// store count in result
result.push_back( Element(count, it->second) );
it = last;
}
for (auto it = result.begin(); it != result.end(); ++it) {
std::cout << it->first << " ";
for (std::size_t i = 0; i < 3; ++i)
std::cout << it->second[i] << " ";
std::cout << "\n";
}
}
在Ideone上输出
注意:排序元素上的循环可能看起来O(N^2)
(线性std::find_if
嵌套在线性中for
),但这是O(N)
因为最后一个循环语句it = last
跳过了已搜索的元素。