以一种漂亮的STL方式检查一个范围是否是另一个范围的子范围

Check if one range is a subrange of another range in a nice, STL-ish way

本文关键字:范围 范围是 一个 另一个 是否是 STL 一种 漂亮 方式 检查      更新时间:2023-10-16

假设我们有两个范围r1 = [first1, last1)r2 = [first2, last2)

假设r2r1子范围,当存在这样的i>=0时,

  1. [first1 + i, first1 + i + last2 - first2)是有效范围

  2. 对于[0, last2 - first2)中的所有j,以下情况成立:

    *(first1 + i + j) == *(first2 + j)
    

嵌套循环可以很容易地确定r2是否是r1的子范围,或者甚至是具有对std::equal模板的嵌套调用的一个循环。有没有一种更STL风格、更简洁的方式来用C++表达同样的想法?C++0x解决方案也很受欢迎。提前谢谢。

我认为std::search正是您想要的。从…起http://www.cplusplus.com/reference/algorithm/search/[std::search]"在范围[first1,last1)中搜索[first2,last2)定义的序列的第一次出现,并将迭代器返回到其第一个元素。"

这是我之前的评论:

#include <iostream>
#include <vector>
#include <iterator>
template<class MyIterator>
bool is_subrange(const MyIterator& first1, const MyIterator& last1, const MyIterator& first2, const MyIterator& last2)
{
   return std::distance(first1, first2) >=0 && std::distance(last2, last1) >= 0;
}
int main()
{
   std::vector<int> v;
   for (int i=0; i < 100; ++i)
      v.push_back(i);
   std::cout << std::distance(v.begin(), v.end()) << std::endl;
   std::cout << std::distance(v.end(), ++v.begin()) << std::endl;
   std::cout << is_subrange(v.begin(), v.end(), ++v.begin(), --v.end()) << std::endl;
   std::cout << is_subrange(++v.begin(), v.end(), v.begin(), --v.end()) << std::endl;
   return 0;
}

这避免了在处理向量等相同简单容器内的子范围时比较每个元素。

当然,函数is_subrange()非常简单,但对于列表来说会变得更复杂,因为它们是双重链接的,因此距离永远不会是负的,例如std::distance(l.begin(),l.end())==1和std::distance(l.end(。[100,0]和[20,4]的范围也不由这个简单的样本处理,但它是可行的。

无论如何,std::search()将完成Mark-b 之前发布的工作

欢呼,