从二维向量中找出最小向量元素的更好方法
Better way to find out smallest sized vector element from 2D vector
我正在尝试从 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
是否有更好的方法来获得相同的结果?
Is there a better way to get the same result?
使用标准库,即 std::min_element
并通过 lambda 自定义比较。
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";
选项 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';
}
为了使代码更具可读性,最好使用标准算法。
例如
#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;
}
我正在尝试从 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
是否有更好的方法来获得相同的结果?
Is there a better way to get the same result?
使用标准库,即 std::min_element
并通过 lambda 自定义比较。
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";
选项 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';
}
为了使代码更具可读性,最好使用标准算法。
例如
#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;
}