从四个 std::vector 对象中选择元素最多的一个

发布于 2024-08-10 04:57:47 字数 236 浏览 7 评论 0原文

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

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

显然,一旦至少两个向量中有相同数量的元素,这就会给我带来麻烦。

有人能想出一个优雅的解决方案吗?

I have four std::vector containers that all might (or might not) contain elements. I want to determine which of them has the most elements and use it subsequently.

I tried to create a std::map with their respective sizes as keys and references to those containers as values. Then I applied std::max on the size() of each vector to figure out the maximum and accessed it through the std::map.

Obviously, this gets me into trouble once there is the same number of elements in at least two vectors.

Can anyone think of a elegant solution ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

三生殊途 2024-08-17 04:57:47

这件事你想得太严重了。你只有四个向量。您可以通过 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;

编辑:

现在有了指针!

编辑(280Z28):

现在有参考资料! :)

编辑:

带有引用的版本将不起作用。帕维尔·米纳耶夫(Pavel Minaev)在评论中很好地解释了这一点:

没错,代码使用
参考。第一行,其中
声明 max,不会导致复制。
但是,以下所有行都会导致
一个副本,因为当你写 max =
矢量N
,如果max是一个参考,它
不会导致引用被引用
到不同的向量(参考
不能更改为引用
不同的对象一旦初始化)。
相反,它与
max.operator=(vectorN),这只是
导致 vector1 被清除并且
被包含的元素替换
vectorN,复制它们。

指针版本可能是您的最佳选择:它快速、低成本且简单。

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;

You're severely overthinking this. You've only got four vectors. You can determine the largest vector using 3 comparisons. Just do that:

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;

EDIT:

Now with pointers!

EDIT (280Z28):

Now with references! :)

EDIT:

The version with references won't work. Pavel Minaev explains it nicely in the comments:

That's correct, the code use
references. The first line, which
declares max, doesn't cause a copy.
However, all following lines do cause
a copy, because when you write max =
vectorN
, if max is a reference, it
doesn't cause the reference to refer
to a different vector (a reference
cannot be changed to refer to a
different object once initialized).
Instead, it is the same as
max.operator=(vectorN), which simply
causes vector1 to be cleared and
replaced by elements contained in
vectorN, copying them.

The pointer version is likely your best bet: it's quick, low-cost, and simple.

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;
十级心震 2024-08-17 04:57:47

这是一个解决方案(除了 Pesto 过于直接的方法之外) - 出于解释目的,我避免使用 bind 和 C++0x lambda,但您可以使用它们来消除对单独函数的需要。我还假设两个向量具有相同数量的元素,选择哪一个是无关紧要的。

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

Here's one solution (aside from Pesto's far-too-straightforward approach) - I've avoided bind and C++0x lambdas for explanatory purposes, but you could use them to remove the need for a separate function. I'm also assuming that with two vectors with an equal number of elements, which one is picked is irrelevant.

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> >);
}
别把无礼当个性 2024-08-17 04:57:47

这是我非常简单的方法。唯一感兴趣的是你只需要基本的 C++ 就可以理解它。

 vector<T>* v[] = {&v1, &v2, &v3, &v4}, *max=&v1;
 for(int i=1; i < 4; ++i)
     if (v[i]->size() > max->size()) max = v[i];

Here is my very simple method. Only interest is that you just need basic c++ to understand it.

 vector<T>* v[] = {&v1, &v2, &v3, &v4}, *max=&v1;
 for(int i=1; i < 4; ++i)
     if (v[i]->size() > max->size()) max = v[i];
水溶 2024-08-17 04:57:47

这是 coppro 答案的修改版本,使用 std::vector 来引用任意数量的向量进行比较。

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

void foo () {
    // Define vector holding pointers to the original vectors
    typedef vector< vector<T>* > VectorPointers;

    // Fill the list
    VectorPointers vecs;
    vecs.push_back(&vec1);
    vecs.push_back(&vec2);
    vecs.push_back(&vec3);
    vecs.push_back(&vec4);        

    vector<T>& vec = std::min_element(
        vecs.begin(), 
        vecs.end(), 
        size_less<vector<T> >
    );
}

This is a modified version of coppro's answer using a std::vector to reference any number of vectors for comparison.

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

void foo () {
    // Define vector holding pointers to the original vectors
    typedef vector< vector<T>* > VectorPointers;

    // Fill the list
    VectorPointers vecs;
    vecs.push_back(&vec1);
    vecs.push_back(&vec2);
    vecs.push_back(&vec3);
    vecs.push_back(&vec4);        

    vector<T>& vec = std::min_element(
        vecs.begin(), 
        vecs.end(), 
        size_less<vector<T> >
    );
}
恬淡成诗 2024-08-17 04:57:47

我完全赞成过度思考的事情:)
对于查找组中最高/最低元素的一般问题,我将使用带有比较器的priority_queue:
(无耻地从coppro复制,并修改......)

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


vector* highest()
{
  priority_queue<vector<T>, size_less<T> > myQueue;
  ...
  ...
  return myQueue.top();
}  

I'm all for over-thinking stuff :)
For the general problem of finding the highest/lowest element in a group, I would use a priority_queue with a comparator:
(copying shamelessly from coppro, and modifying...)

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


vector* highest()
{
  priority_queue<vector<T>, size_less<T> > myQueue;
  ...
  ...
  return myQueue.top();
}  
自由如风 2024-08-17 04:57:47

您可以使用 std::multimap。这允许使用相同的密钥进行多个条目。

You could use a std::multimap. That allows multiple entries with the same key.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文