首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何比较std::map中的所有项目?

如何比较std::map中的所有项目?
EN

Stack Overflow用户
提问于 2019-12-06 00:01:42
回答 5查看 420关注 0票数 2

我想将我的std::map中的所有值相互比较。

我被困住了:对于线性容器,比如向量,我会遍历索引i=1; v[i].isUniform(v[i-1])。但我不能用地图做到这一点。我期待着听到聪明的想法。

下面是我想要实现的一些伪代码:

代码语言:javascript
运行
复制
class MyData
{
public:
    bool isUniform(const MyData& other) const
    {
        return this->speed == other.speed && this->ban == other.ban;
    }

private:
    bool ban;
    int  speed;
}

std::map<int, MyData> myMap;

bool allUniform = true;
for(item_1, item_2 : myMap) // how to implement this?
{
    if(!item_1.isUniform(item_2))
    {
        allUniform = false;
    }
}

要做到这一点,最优雅(可读且高效)的方式是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-12-06 00:11:43

代码语言:javascript
运行
复制
for(item_1, item_2 : myMap) // how to implement this?

但如果它们都相等(假设isUniform是传递的和对称的),这就等同于说它们都等于第一个元素。因此,您可以将每个元素与第一个元素进行比较。

天真地,我们得到:

代码语言:javascript
运行
复制
bool allUniform(std::map<int, MyData> const &m)
{
    if (m.empty()) return true; // or whatever makes sense for you

    auto first = m.begin();
    for (auto current = m.begin(); ++current != m.end(); )
    {
        if (!first->second.isUniform(current->second))
        {
            return false;
        }
    }
    return true;
}

如果您不介意将第一个元素与其本身进行比较,那么您可以简化此过程,因为实际上大多数复杂性只是避免了这一点。

在另一个答案中使用std::adjacent_findstd::all_of解决方案可能会更好,如下所示。

代码语言:javascript
运行
复制
bool allUniform(std::map<int, MyData> const &m)
{
    auto first_non_uniform =
        std::adjacent_find(
            m.begin(), m.end(),
            [](auto left, auto right)
            {
                return !(left->second.isUniform(right->second));
            }
           );

    return first_non_uniform == m.end();
}
票数 2
EN

Stack Overflow用户

发布于 2019-12-06 00:18:24

您可以使用std::all_of和lambda来实现这一点。这看起来就像

代码语言:javascript
运行
复制
bool allUniform = std::all_of(std::next(myMap.begin()), 
                              myMap.end(), 
                              [&myMap](const auto& pair)
                              { return myMap.begin()->second.isUniform(pair.second); });

这是从[1, N)开始的,根据第一个元素对每个元素调用isUniformall_of还会进行短路,这样一旦出现不一致的结果,它就会结束。

票数 4
EN

Stack Overflow用户

发布于 2019-12-06 00:21:09

isUniform()是可传递的吗?也就是说,对于任何3个MyData对象,它是否遵循以下规则:

代码语言:javascript
运行
复制
 isUniform(A, B) && isUniform(B, C) == isUniform(A, C)

如果是这样,那么您只需要O(n)个比较。下面是我的测试代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <map>

using namespace std;

class MyData {
public:
    int value;
    MyData(int _value) : value(_value) {}

    bool isUniform(const MyData &obj) const { return value == obj.value; }

    static void checkMap(map<int, MyData> myMap) {
         bool allUniform = true;
         MyData * firstItem = nullptr;

         for (auto it = myMap.begin(); allUniform && it != myMap.end(); ++it) {
             if (firstItem == nullptr) {
                  firstItem = &it->second;
             }
             else {
                  allUniform = firstItem->isUniform(it->second);
             }
         }

         cout << "All Uniform: " << (allUniform ? "Yes" : "No") << endl;
    }
};

int main(int, char **) {
    map<int, MyData> map1;
    map<int, MyData> map2;
    MyData a1(1);
    MyData b1(1);
    MyData b2(2);
    MyData c1(1);

    // Should be uniform
    map1.insert(std::pair<int, MyData>(1, a1));
    map1.insert(std::pair<int, MyData>(2, b1));
    map1.insert(std::pair<int, MyData>(3, c1));
    MyData::checkMap(map1);

    // Should not be uniform
    map2.insert(std::pair<int, MyData>(1, a1));
    map2.insert(std::pair<int, MyData>(2, b2));
    map2.insert(std::pair<int, MyData>(3, c1));
    MyData::checkMap(map2);

    return 0;
}

输出如下:

代码语言:javascript
运行
复制
$ g++ -std=c++0x Foo.cpp -o Foo && Foo
All Uniform: Yes
All Uniform: No
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59198986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档