从二维向量中找出最小向量元素的更好方法

Posted

技术标签:

【中文标题】从二维向量中找出最小向量元素的更好方法【英文标题】:Better way to find out smallest sized vector element from 2D vector 【发布时间】:2019-11-18 00:36:31 【问题描述】:

我正在尝试从vector<vector<int>> 中找出最小的vector<int> 元素。

这是我的代码,但它对向量进行了两次迭代。

#include <iostream>
#include <vector>
#include <limits>

int main()

    std::vector<std::vector<int>> foo = 1,2,3,4, 1,2, 1,2,3,4,5, 1,2,3;
    size_t smallestNumElems = std::numeric_limits<size_t>::max();
    for (size_t i = 0; i < foo.size(); ++i)
    
        const size_t numElems = foo[i].size();
        if (smallestNumElems > numElems)
            smallestNumElems = numElems;
    
    for (size_t i = 0; i < foo.size(); ++i)
    
        if (smallestNumElems == foo[i].size())
        
            for (size_t j = 0; j < foo[i].size(); ++j)
                std::cout << foo[i][j] << '\n';
            break;
        
    

结果:

1
2
Program ended with exit code: 0

有没有更好的方法来获得相同的结果?

【问题讨论】:

std::min_element 带有合适的lambda 用于比较器。 您可以存储一个指向最小 vec 的指针并使用它进行迭代。 【参考方案1】:

为了使代码更具可读性,最好使用标准算法。

例如

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main() 

    std::vector<std::vector<int>> foo = 
    
         1, 2, 3, 4,  1, 2 ,  1, 2, 3, 4, 5 ,  1, 2, 3 

    ;

    auto min_size = []( const auto &v1, const auto &v2 )
    
        return v1.size() < v2.size();
    ;

    auto it = std::min_element( std::begin( foo ), std::end( foo ), min_size );

    for ( const auto &value : *it ) std::cout << value << ' ';
    std::cout << '\n';

    return 0;

程序输出是

1 2 

如果你的编译器支持 C++ 17 标准,那么 lambda 表达式也可以写成这样

    auto min_size = []( const auto &v1, const auto &v2 )
    
        return std::size( v1 ) < std::size( v2 );
    ;

如果要像您一样使用循环,然后转义两个找到具有最小大小的向量的循环,那么您可以编写

#include <iostream>
#include <vector>

int main() 

    std::vector<std::vector<int>> foo = 
    
         1, 2, 3, 4,  1, 2 ,  1, 2, 3, 4, 5 ,  1, 2, 3 

    ;

    using size_type = std::vector<std::vector<int>>::size_type;

    size_type min_vector = 0;

    for ( size_type i = 1; i < foo.size(); ++i )
    
        if ( foo[i].size() < foo[min_vector].size() )
        
            min_vector = i; 
        
    

    for ( const auto &value : foo[min_vector] ) std::cout << value << ' ';
    std::cout << '\n';

    return 0;

【讨论】:

【参考方案2】:

选项 1:

int main()

    std::vector<std::vector<int>> foo = 1,2,3,4, 1,2, 1,2,3,4,5, 1,2,3;
    size_t smallestNumElems = std::numeric_limits<size_t>::max();
    std::vector<int>* smallestEntry = nullptr; // Store a reference to the smallest entry in here
    for (size_t i = 0; i < foo.size(); ++i)
    
        const size_t numElems = foo[i].size();
        if (smallestNumElems > numElems) 
            smallestNumElems = numElems;
            smallestEntry = &foo[i];
        
    
    for (size_t i = 0; i < smallestEntry->size(); ++i)
       std::cout << smallestEntry->at(i) << '\n';

选项 2:

#include <algorithm>
// ... Stuff
int main()

    std::vector<std::vector<int>> foo = 1,2,3,4, 1,2, 1,2,3,4,5, 1,2,3;

    auto& smallest = *std::min_element(foo.begin(), foo.end(), 
        [](std::vector<int> const& a, std::vector<int> const& b)  // <- could replace std::vector<int> with auto
            return a.size() < b.size(); 
        
    );

    for (size_t i = 0; i < smallest.size(); ++i)
       std::cout << smallest.at(i) << '\n';

【讨论】:

@JeJo 我们想要的是长度比较,而不是字典顺序的比较【参考方案3】:

有没有更好的方法来获得相同的结果?

使用标准库,即std::min_element,并通过 lamdba 自定义比较。

const auto smallestSizeVec = std::min_element(foo.cbegin(), foo.cend(),
    [](const auto& v1, const auto& v2)  return v1.size() < v2.size(); );

std::cout << "The smallest vector has size " << smallestSizeVec->size() << "\n";

【讨论】:

@JeJo 但这需要问题中给出的向量。 operator &lt; 用于向量执行字典比较。我的猜测是问题中显示的输入是示例性的。

以上是关于从二维向量中找出最小向量元素的更好方法的主要内容,如果未能解决你的问题,请参考以下文章

查找向量中的最小项目列表

matlab 怎么找出二维矩阵中最大值的位置

matlab找出两个向量都不为零的元素,并找出元素的位置

在c ++中给出两个整数向量(相同的大小和类型),我想从最小到最大的元素对一个进行排序并更改第二个向量的顺序[重复]

如何在向量的给定索引范围内找到最小元素?

查找向量的向量的最大值/最小值