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

时间:2011-06-28 14:02:24

标签: c++ stl c++11

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

假设r2r1 子范围 ,如果存在i>=0那么<{1}}

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

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

    *(first1 + i + j) == *(first2 + j)
    
  3. 嵌套循环可以轻松确定r2r1的子范围,还是一个嵌套调用std::equal模板的循环。是否有更多的STL-ish,简洁的方式来表达C ++中的相同想法? C ++ 0x解决方案也是受欢迎的。提前谢谢。

2 个答案:

答案 0 :(得分:3)

我认为std::search正是您所寻找的。从http://www.cplusplus.com/reference/algorithm/search/ [std::search]“搜索范围[first1,last1],查找[first2,last2]定义的序列的第一次出现,并将迭代器返回到其第一个元素。”

答案 1 :(得分:0)

这是你先前的评论:

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

这避免了在处理像vector这样的简单容器中的子范围时比较每个元素。

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

无论如何,std :: search()将完成以前由Mark-b

发布的工作

欢呼声,