c++ - multimap 智能按键排序

标签 c++ sorting multimap accumulate

我已经研究这个问题一段时间了。我有 3 个 .txt 文件,其中包含一些要在 multimap 中读取和排列的内容,

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

表示 a 中有一个 1,a 中有两个 2,b 中有一个 3,b 中有两个 4...等等。

我的代码(如下)错误地产生了这个结果:

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();

最佳答案

所以。完全不清楚为什么要用这种复杂的数据结构伤害自己。你有一把 key ,有两部分。因此,让我们为您的 std::map 制作 key 一个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

但我假设所有键都应该正确排序,这就是我的输出所做的。

关于c++ - multimap 智能按键排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24601122/

相关文章:

javascript - 对 javascript 数组进行排序,使空白值始终位于底部

c# - 如何将MultiMap .Net转发到Java?

C++ 结构、公共(public)数据成员和继承

c++ - 根据object的成员变量查找STL::set<object>中的元素

c++ - 如何在 C++ 中处理一副纸牌

c++ - 插入到 multimap 导致段错误

c++ - 如何循环 multimap 以获得每个键的第一个键值对?

c++ - nullptr_t 是默认的可构造类型吗?

java - 如何按某种自然顺序对链表进行排序?

Javascript:数组、对象、排序和原型(prototype)?