有没有一种标准的方法来比较C ++中的两个范围?

时间:2011-03-23 12:24:50

标签: c++ stl iterator

按范围我的意思是一对迭代器。在伪C ++中:

std::vector<int> v1 = { 1, 2, 3, 4, 5 };
std::vector<int> v2 = { 2, 3, 4 };
if( std::compare_range( v1.begin() + 1, v1.end() - 1, v2.begin(), v2.end() ) {
    std::cout << "Alright\n";
}

compare_range当然是我正在寻找的功能。

免责声明:我知道,这是一个非常简单的写作功能。但是像所有程序员一样,我试图变得懒惰; - )

6 个答案:

答案 0 :(得分:28)

std::equal是您正在寻找的功能模板。

if (std::equal(v1.begin() + 1, v1.end() - 1, v2.begin())
{
    std::cout << "Alright\n";
}

请注意,std::equal只需要三个参数,而不是四个。

答案 1 :(得分:7)

使用std::equal - 它也支持范围。

答案 2 :(得分:6)

似乎没有标准的“单功能”方法。提到std :: equal假设,第二个范围不短于第一个范围。例如,当第二个间隔为空时,这可能会导致内存损坏。当第二个范围较大时,它也没有给出答案。

需要std :: equal和std :: distance的组合,或者自编函数:

template <class InputIterator1, class InputIterator2>
bool safe_equal( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 )
{
  return ( std::distance( first1, last1 ) == std::distance( first2, last2 ) )
     && std::equal( first1, last1, first2 );
}

上面的函数可能会因为不是随机访问迭代器而遍历包含两次,而是使用标准函数。如果这是不可接受的,编写自己的实现可能是合理的。

答案 3 :(得分:4)

如果您有办法确定这两个范围 std::equal将完成相同数量的元素。在 练习,这似乎不是经常对我来说, 事实上我拥有std::equal的大部分用途 确定一个范围是否是另一个范围的前缀。

对于实际比较,我发现std::lexicographical_compare 更有用,虽然它与promesses的关系是一个 秩序,而不是等价。对于等价,您可以应用它 两次,例如

   !lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())
&& !lexicographical_compare(b.begin(), b.end(), a.begin(), a.end())

但这几乎意味着两次比较元素(除非 一开始就有差异。)

答案 4 :(得分:2)

Boost中有一个函数可以检查范围的大小:

boost::range::equal

答案 5 :(得分:0)

使用 C++20:

if (std::ranges::equal( std::ranges::subrange{ v1.begin() + 1, v1.end() - 1 }, v2) {
    std::cout << "Alright\n";
}

或者,如果需要less/greater-check

if (auto cmp = std::lexicographical_compare_three_way(v1.begin() + 1, v1.end() - 1, v2.begin(), v2.end()); cmp == 0) {
    std::cout << "Alright\n";
}
else if (cmp < 0) {//...}

std::vector 是一个连续容器,因此对于 STL 算法,不需要额外的范围大小检查。