Мультикарта интеллектуальная сортировка по ключу

Я работал над этой проблемой уже некоторое время. У меня есть 3. TXT-файла, содержащие некоторые вещи для чтения и упорядочить в мультикарте,

std::multimap<std::string, std::multimap<int, int>>

но если ключ уже существует, я увеличиваю значение и, если ключ уникален, я помещаю значение в карту.

3 файла .txt (обозначенных «x», «y» и «z») содержат это:

«x.txt» содержит первичные ключи:

a a a b b b c c c d d d e e e

«y.txt» содержит вторичные ключи:

1 2 2 3 4 4 5 4 4 2 6 6 6 6 6

и «z.txt», который считает вторичные ключи, содержит:

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Желаемый вывод это:

1 : 1
2 : 2
3 : 1
4 : 2
5 : 1
4 : 2
2 : 1
6 : 2
6 : 3

Который заявляет, что есть один 1 в a, два 2 в a, один 3 в b, два 4 в b … и так далее.

Мой код (ниже) неправильно дает этот результат:

1 : 1
2 : 1
2 : 1
2 : 1
3 : 1
4 : 1
4 : 1
5 : 1
6 : 1
6 : 1
6 : 1

Вот код: Есть предложения?

//needed to output your result (print map)
template<typename a, typename b>
void print1(const std::multimap<a, b>& thing){
for (std::multimap<a,b>::const_iterator it = begin(thing); it != thing.end(); it++){
std::cout << it->first << " : " << it->second << std::endl;
}
}std::ifstream X("x.txt");
std::ifstream Y("y.txt");
std::ifstream Z("z.txt");typedef std::multimap<int, int> Y_Z;
typedef std::multimap<std::string, Y_Z> X_Y_Z;

typedef std::pair<int, int> pair_y_z;
typedef std::pair<std::string, Y_Z> pair_x_y_z;

Y_Z y_z;
X_Y_Z x_y_z;

std::string x_;
int y_;
int z_;if (X){
while (X >> x_, Y >> y_, Z >> z_){

if (x_y_z.empty()) {
y_z.insert(pair_y_z(y_, z_));
x_y_z.insert(pair_x_y_z(x_, y_z));
}
else {

X_Y_Z::iterator first_iter = x_y_z.find(x_);
X_Y_Z::iterator last_iter = x_y_z.upper_bound(x_);

if (x_y_z.find(x_) == x_y_z.end()) {
y_z.insert(pair_y_z(y_, z_));
x_y_z.insert(pair_x_y_z(x_, y_z));
}
else{
for (; first_iter != last_iter; first_iter++){
if (x_y_z.find(x_)->second.find(y_) == x_y_z.find(x_)->second.end()){
//no match
y_z.insert(pair_y_z(y_, z_));
x_y_z.insert(pair_x_y_z(x_, y_z));
break;
}
else{
//found match
x_y_z.find(x_)->second.find(y_)->second += z_;
break;
}
}
}
}
}
}

std::cin.get();
print1(y_z);
std::cin.get();

0

Решение

Так. Совершенно непонятно, почему вы наносите себе вред этой сложной структурой данных. У вас есть ключ с двумя частями. Итак, давайте сделаем ключ к вашему std::map std::pair<T1, T2>,

Если мы сделаем это, код станет невероятно простым.

Исходный код:

#include <iostream>
#include <fstream>
#include <utility>
#include <map>

int main() {
std::ifstream X("x.txt");
std::ifstream Y("y.txt");
std::ifstream Z("z.txt");

std::map<std::pair<std::string, int>, int> data;

std::string x_;
int y_;
int z_;

while (X >> x_, Y >> y_, Z >> z_)
data[std::make_pair(x_, y_)] += z_;

for (auto const & element : data)
std::cout << std::get<1>(element.first) << " : " << element.second << "\n";
}

Выход:

1 : 1
2 : 2
3 : 1
4 : 2
4 : 2
5 : 1
2 : 1
6 : 2
6 : 3

Дальнейшие вопросы:

Есть одно несоответствие между моим выводом и желаемым выводом, но я думаю, что это ошибка в том, что вы ожидаете.

Ваш текущий вывод ожидает:

{a, 1} : 1
{a, 2} : 2
{b, 3} : 1
{b, 4} : 2
{c, 5} : 1  <--- note that this key is out of order with the next one. 5 > 4.
{c, 4} : 2
{d, 2} : 1
{d, 6} : 2
{e, 6} : 3

Но я предполагаю, что все ключи должны быть отсортированы правильно, что и делает мой вывод.

2

Другие решения

Я не вижу в вашем описании проблемы ничего, что требовало бы мультикарты. Просто используйте std::map вместо.

Кроме того, избавиться от y_z, Каждый раз, когда вы используете его, кажется, что вы должны использовать x_y_z[x],

0