#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";
}
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8dmVjdG9yPgogCnR5cGVkZWYgc3RkOjpwYWlyPGludCwgc3RkOjphcnJheTxjaGFyLCAzPiA+IEVsZW1lbnQ7CnN0ZDo6dmVjdG9yPCBFbGVtZW50ID4gdjsKc3RkOjp2ZWN0b3I8IEVsZW1lbnQgPiByZXN1bHQ7CiAKaW50IG1haW4oKQp7CiAgICAgICAgdi5wdXNoX2JhY2soIEVsZW1lbnQoMSwgc3RkOjphcnJheTxjaGFyLCAzPnt7J2EnLCAnYicsICdjJ319KSApOwogICAgICAgIHYucHVzaF9iYWNrKCBFbGVtZW50KDIsIHN0ZDo6YXJyYXk8Y2hhciwgMz57eydhJywgJ2InLCAnYyd9fSkgKTsKICAgICAgICB2LnB1c2hfYmFjayggRWxlbWVudCgxLCBzdGQ6OmFycmF5PGNoYXIsIDM+e3snYycsICdkJywgJ2UnfX0pICk7CiAgICAgICAgdi5wdXNoX2JhY2soIEVsZW1lbnQoMSwgc3RkOjphcnJheTxjaGFyLCAzPnt7J2InLCAnYycsICdkJ319KSApOwogICAgICAgIHYucHVzaF9iYWNrKCBFbGVtZW50KDMsIHN0ZDo6YXJyYXk8Y2hhciwgMz57eydiJywgJ2MnLCAnZCd9fSkgKTsKIAogICAgICAgIC8vIE8oTiBsb2coTikgKSBjb21wbGV4aXR5CiAgICAgICAgc3RkOjpzb3J0KHYuYmVnaW4oKSwgdi5lbmQoKSwgW10oRWxlbWVudCBjb25zdCYgZTEsIEVsZW1lbnQgY29uc3QmIGUyKXsKICAgICAgICAgICAgICAgIC8vIGNvbXBhcmUgdGhlIGFycmF5IHBhcnQgb2YgdGhlIHBhaXI8aW50LCBhcnJheT4KICAgICAgICAgICAgICAgIHJldHVybiBlMS5zZWNvbmQgPCBlMi5zZWNvbmQ7IAogICAgICAgIH0pOwogCiAgICAgICAgLy8gTyhOKSBjb21wbGV4aXR5CiAgICAgICAgZm9yIChhdXRvIGl0ID0gdi5iZWdpbigpOyBpdCAhPSB2LmVuZCgpOykgewogICAgICAgICAgICAgICAgLy8gZmluZCBuZXh0IGVsZW1lbnQKICAgICAgICAgICAgICAgIGF1dG8gbGFzdCA9IHN0ZDo6ZmluZF9pZihpdCwgdi5lbmQoKSwgWz1dKEVsZW1lbnQgY29uc3QmIGVsZW0pewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXQtPnNlY29uZCAhPSBlbGVtLnNlY29uZDsgICAgIAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIGFjY3VtdWxhdGUgdGhlIGNvdW50cwogICAgICAgICAgICAgICAgYXV0byBjb3VudCA9IHN0ZDo6YWNjdW11bGF0ZShpdCwgbGFzdCwgMCwgW10oaW50IHN1YiwgRWxlbWVudCBjb25zdCYgZWxlbSkgewogICAgCQlyZXR1cm4gc3ViICsgZWxlbS5maXJzdDsKCQl9KTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gc3RvcmUgY291bnQgaW4gcmVzdWx0CiAgICAgICAgICAgICAgICByZXN1bHQucHVzaF9iYWNrKCBFbGVtZW50KGNvdW50LCBpdC0+c2Vjb25kKSApOyAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaXQgPSBsYXN0OwogICAgICAgIH0KIAogICAgICAgIGZvciAoYXV0byBpdCA9IHJlc3VsdC5iZWdpbigpOyBpdCAhPSByZXN1bHQuZW5kKCk7ICsraXQpIHsKICAgICAgICAgICAgICAgIHN0ZDo6Y291dCA8PCBpdC0+Zmlyc3QgPDwgIiAiOwogICAgICAgICAgICAgICAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IDM7ICsraSkKICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpjb3V0IDw8IGl0LT5zZWNvbmRbaV0gPDwgIiAiOwogICAgICAgICAgICAgICAgc3RkOjpjb3V0IDw8ICJcbiI7CiAgICAgICAgfQp9