在四个std :: vector对象中选择具有最多元素的对象

luu*_*uke 1 c++ algorithm stdvector

我有四个std :: vector容器,它们都可能(或可能不)包含元素.我想确定哪些元素具有最多元素并随后使用它.

我尝试创建一个std :: map,它们各自的大小作为键,并将这些容器的引用作为值.然后我在每个向量的size()上应用std :: max来计算最大值并通过std :: map访问它.

显然,一旦在至少两个向量中存在相同数量的元素,这就会让我陷入困境.

谁能想到一个优雅的解决方案?

Pes*_*sto 13

你严厉地过度思考这个问题.你只有四个向量.您可以使用3次比较确定最大的向量.就这样做:

std::vector<blah>& max = vector1;
if (max.size() < vector2.size()) max = vector2;
if (max.size() < vector3.size()) max = vector3;
if (max.size() < vector4.size()) max = vector4;
Run Code Online (Sandbox Code Playgroud)

编辑:

现在有了指针!

编辑(280Z28):

现在有参考!:)

编辑:

带引用的版本不起作用.Pavel Minaev在评论中很好地解释了这一点:

这是正确的,代码使用引用.第一行声明了max,不会导致副本.但是,所有后续行都会导致复制,因为在写入时max = vectorN,如果max是引用,则不会导致引用引用不同的向量(初始化后,引用不能更改为引用其他对象).相反,它是相同的 max.operator=(vectorN),它只是简单地导致vector1vectorN复制它们中包含的元素清除和替换 .

指针版本可能是您最好的选择:它快速,低成本,简单.

std::vector<blah> * max = &vector1;
if (max->size() < vector2.size()) max = &vector2;
if (max->size() < vector3.size()) max = &vector3;
if (max->size() < vector4.size()) max = &vector4;
Run Code Online (Sandbox Code Playgroud)

  • 我会使用指针,以避免在这里复制.更好的是,一个引用 - 但这需要在初始化中进行所有上述比较. (6认同)
  • 这是正确的,代码使用引用.第一行声明`max`,不会导致副本.但是,所有后面的行确实会导致副本,因为当你写`max = vectorN`时,如果`max`是一个引用,它不会导致引用引用不同的向量(引用不能更改为引用初始化后的另一个对象).相反,它与`max.operator =(vectorN)`相同,它简单地导致`vector1`被清除并被'vectorN`中包含的元素替换,复制它们. (2认同)

cop*_*pro 9

这是一个解决方案(除了Pesto非常简单的方法) - bind为了解释的目的,我避免使用C++ 0x lambdas,但你可以使用它们来消除对单独函数的需求.我也假设有两个具有相同数量元素的向量,其中一个被挑选是无关紧要的.

template <typename T> bool size_less (const T* lhs, const T* rhs) {
    return lhs->size() < rhs ->size();
}

void foo () {
    vector<T>* vecs[] = {&vec1, &vec2, &vec3, &vec4};
    vector<T>& vec = std::min_element(vecs, vecs + 4, size_less<vector<T> >);
}
Run Code Online (Sandbox Code Playgroud)

  • @coppro:你可能想要使用`vecs + sizeof(vecs)/ sizeof(vecs [0])`而不是`vecs + 4`.我会把`size_less`作为一个函数对象,因为那些内联更好. (2认同)