【问题标题】:Maps addition with key as a structure以键为结构的映射添加
【发布时间】:2017-01-11 03:09:26
【问题描述】:
    typedef struct A{
      string id;
      long date;
      // operator = and < overloading
    }Test;

Map<Test, double> testMap[2];

在代码中,testMap 数组填充了键和值以及一些业务逻辑。

我需要为每个 A.id 计算两个映射的总双精度值。请注意,总和应仅基于 A.id 而不是整个结构键。
为此,我可以使用 for 循环应用正常的蛮力方法并获得结果。

但我正在尝试寻找可以优化代码的此问题的任何替代解决方案。请提出建议。

【问题讨论】:

  • 你不使用这个有什么原因吗:Map testMap[2]; ?
  • 对于每个 id ,我们可能在不同的日期有不同的交易。所以将地图键设置为 id 和日期的组合。
  • 似乎map&lt;string, pair&lt;vector&lt;double&gt;, long&gt;&gt; test_map[2] 在这种特定情况下可能会更好。
  • 有什么理由不使用std::array&lt;std::map&lt;Test, double&gt;, 2&gt; testMaps

标签: c++ dictionary stl


【解决方案1】:

这样做的一种方法是应用嵌套的std::accumulate 两次,一次对 arrays 求和,然后对每个数组求和 map 内容:

struct Test
{
    string id;
    long date;
    bool operator<(Test const& test) const
    {
        if(date == test.date)
            return id < test.id;
        return date < test.date;
    }
};

double sum_per_id(std::array<std::map<Test, double>, 2> const& testMapArray,
    std::string const& id)
{
    return std::accumulate(std::begin(testMapArray), std::end(testMapArray), 0.0,
    [&id](double d, std::map<Test, double> const& testMap)
    {
        return d + std::accumulate(std::begin(testMap), std::end(testMap), 0.0,
        [&id](double d, std::map<Test, double>::value_type const& p)
        {
            if(id == p.first.id)
                return d + p.second;
            return d;
        });
    });
}

int main()
{
    std::array<std::map<Test, double>, 2> testMapArray;

    testMapArray[0][{"A", 0}] = 0.1;
    testMapArray[0][{"B", 1}] = 0.2;

    testMapArray[1][{"A", 2}] = 0.3;
    testMapArray[1][{"B", 3}] = 0.4;

    std::cout << "sum: " << sum_per_id(testMapArray, "A") << '\n';
}

输出:

sum: 0.4

【讨论】:

  • 在这种情况下 testMapArray[0][{"A", 0}] = 0.1; testMapArray[0][{"A", 1}] = 0.1;第二个键将覆盖第一个键。我认为他希望根据 id 和数据进行比较。
  • @user1438832 是的,你是对的。我专注于求和,而不是他对关键比较器的实现可能是什么。固定。
  • 我觉得这是个好方法!!
  • 我用的是vs2010。我收到与 lambda 表达式相关的错误。我之前从未使用过 c++11。所以我希望上述方法只能在更高版本的visual studio中实现。
  • @user1706047 通过创建函数对象来替换lambdas,可以为早期版本的编译器修改代码。但它不像使用 lambdas 那样清晰或简洁。如果您不能使用C++11,那么我建议您手动构建循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 2019-01-18
  • 2012-01-07
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
相关资源
最近更新 更多