Я представляю один способ повторно использовать точку вставки. Я использую тот факт, что вставки редки.
Я бы использовал отсортированный вектор пар в качестве MapType.
typedef std::vector<std::pair<size_t, size_t>> MapType;
Предполагая, что векторы отсортированы в соответствии с функтором key_comp
. Затем вы можете создать функтор сравнения для своего MapType (здесь я использую лямбда-выражение для этого).
auto comp = [&](std::pair<size_t, size_t>& p1, std::pair<size_t, size_t> const& p2)
{
return key_comp(p1.first,p2.first);
};
Теперь для каждого вектора в v
вы можете повторно использовать свои прошлые точки вставки, потому что вы знаете, что элементы отсортированы.
Вот полный код
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
typedef std::vector<std::pair<size_t, size_t>> MapType;
int main()
{
const std::vector<std::vector<size_t>> v = {
{4, 10, 12, 18, 20, 28, 34},
{4, 12, 18, 20, 28},
{4, 17, 18, 20, 28},
{4, 17, 18, 20, 28, 37}
};
auto key_comp = [](std::size_t v1, std::size_t v2) {
return v1 < v2;
};
auto comp = [&](std::pair<size_t, size_t>& p1, std::pair<size_t, size_t> const& p2)
{
return key_comp(p1.first,p2.first);
};
MapType counts;
for (const auto& a : v)
{
auto it = counts.begin();
for (const auto& b : a)
{
// You can start from it instead of counts.begin() because vector a is sorted
it = std::lower_bound(it, counts.end(), MapType::value_type(b, 1), comp);
if (it != counts.end() && !(key_comp(b, it->first)))
{
// mut already exist
++(it->second);
} else
{
// mut is new
// Insertion may invalidate iterators so you need to reassign it
it = counts.insert(it, MapType::value_type(b, 1));
}
}
}
for (auto it = counts.begin() ; it != counts.end() ; ++it)
std::cout << it->first << ": " << it->second << "\n";
}
Вывод:
4: 4
10: 1
12: 2
17: 2
18: 4
20: 4
28: 4
34: 1
37: 1
Ссылка на проводник компилятора: https://godbolt.org/z/zoY7KG