Iterator为向量的子集

时间:2015-05-29 22:37:23

标签: c++ c++11 vector range

是否有可能从一个向量中获取一个const迭代器,该向量只能在无效之前迭代某个向量范围?

例如,如果我有一个10个元素的向量,我想返回元素4到7的迭代器。

伪码:

int main()
{
    std::vector<int> vector = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    auto iterator = GetRangedIterator(vector, 4, 7)
    for (const int& num : iterator)
        print num;      // 4, 5, 6, 7
}

5 个答案:

答案 0 :(得分:14)

这非常简单(尽管我将结果称为范围,而不是迭代器)。

一个简单的实现看起来像这样:

template <class Iter>
class range {
    Iter b;
    Iter e;
public:

    range(Iter b, Iter e) : b(b), e(e) {}

    Iter begin() { return b; }
    Iter end() { return e; }
};

template <class Container>
range<typename Container::iterator> 
make_range(Container& c, size_t b, size_t e) {
    return range<typename Container::iterator> (c.begin()+b, c.begin()+e);
}

现在看来,这遵循正常的C ++约定(基于0的计数,你指定的结束超出了范围的结束,而不是它),所以为了得到你要求的输出,你要这样做指定范围3, 7,例如:

for (int num : make_range(vector, 3, 7))
    std::cout << num << ", ";      // 4, 5, 6, 7,

请注意,基于范围的for循环知道如何使用beginend成员函数来告诉它要迭代的范围,所以我们不要# 39;必须处理使迭代器无效或类似的事情,我们只需要指定我们关心的范围的开始和结束。

答案 1 :(得分:5)

您可以使用range-v3库作为Ranges TS will been part of C++20的基础,但该库已经可以与C ++ 11编译器一起使用。以下是:

#include <range/v3/all.hpp>
#include <iostream>
#include <vector>

int main() 
{
    using namespace ranges;

    auto v = view::iota(1, 11) | to_<std::vector<int>>();
    std::cout << view::all(v)  << '\n';

    auto rng = v | view::slice(3, 7); 
    std::cout << rng << '\n';
}

Live Example

答案 2 :(得分:3)

您可以使用此

for( it = v1.begin() + a; it <= v1.begin() + b; it++ )

以下代码是一个小型演示

#include <vector>
#include <iostream>

using namespace std;

int main(){

  vector<int> v1;

  for( int i = 0; i < 50; i++ ){
    v1.push_back( 2*(i+1) );
    cout<<v1.at(i)<<"   ";
  }
  cout<<endl;


  vector<int>::iterator it;

  int a = 5;
  int b = 9;

  for( it = v1.begin() + a; it <= v1.begin() + b; it++ ){

    cout<<(*it)<<"   ";
  }
  cout<<endl; 
}

输出

2   4   6   8   10   12   14   16   18   20   22   24   26   28   30   32   34   36   38   40   42   44   46   48   50   52   54   56   58   60   62   64   66   68   70   72   74   76   78   80   82   84   86   88   90   92   94   96   98   100   
12   14   16   18   20   

答案 3 :(得分:1)

标准库中没有任何内容可以明确地执行此操作,但如果您愿意使用Boost,则可以使用range概念使用以下方法:

auto range = boost::make_iterator_range(v.begin()+3, v.begin()+7);

BOOST_FOREACH(int i, range)
{
    cout << i << endl;
}

这应输出4567

答案 4 :(得分:-1)

您可以使用span

#include <stdio.h>
#include <stdlib.h>
#define MAX 100
//there are 2 queues, and one empty linked list
//take elements from queues and sort it on linked list

struct q {
   int queue[MAX];
   int front;
   int rear;
   int counter;
};

struct node {
    int x;
   struct node *next;
};

typedef struct node node;
typedef struct q queue;


void enqueue(queue **queue, int x) {

    if (!((*queue)->counter == MAX)) {
        (*queue)->rear++;
        (*queue)->counter++;
        if ((*queue)->rear == MAX)
            (*queue)->rear = 0;
        (*queue)->queue[(*queue)->rear] = x;
    }

}

 int dequeue(queue **queue) {

    if (!((*queue)->counter == 0)) {
        int x = (*queue)->queue[(*queue)->front];
        (*queue)->counter--;
        (*queue)->front++;
        if ((*queue)->front == MAX)
            (*queue)->front = 0;
        return x;
    }
    else 
        return - 1;
}

node* sortedInsert(node **root, int x) {
    if (*root == NULL) {
        *root = (node *)malloc(sizeof(node*));
        (*root)->x = x;
        (*root)->next = NULL;
        return root;
    }
    if (x< (*root)->x) {
        node *temp = (node *)malloc(sizeof(node));
        temp->next = root;
        temp->x = x;
        return temp;
    }
    node *iter = *root;
    while (iter->next != NULL && iter->next->x < x) {
        iter = iter->next;
    }
    node *temp = (node *)malloc(sizeof(node));
    temp->x = x;
    temp->next = iter->next;
    iter->next = temp;
    return *root;
}

void printlist(node *root) {

    while (root != NULL) {
        printf("%d \n", root->x);
        root = root->next;
    }
}

void initialize(queue **q) {
    *q = (queue*)malloc(sizeof(queue));
    (*q)->counter = 0;
    (*q)->front = 0;
    (*q)->rear = -1;
}

void sortedlist(queue **q1, queue **q2, node **root) {
    while ((*q1)->counter != 0) {
        sortedInsert(root, dequeue(q1));
    }
    while ((*q2)->counter != 0) {
        sortedInsert(root, dequeue(q2));
    }
}

int main(void) {
printf("hello\n");

    queue *q1 = NULL, *q2 = NULL;
    node *root = NULL;
    initialize(&q1);
    initialize(&q2);
printf("init\n");
    enqueue(&q1, 10);
    enqueue(&q1, 20);
    enqueue(&q1, 30);
    enqueue(&q1, 40);
    enqueue(&q1, 50);
    enqueue(&q1, 60);
    enqueue(&q1, 70);
    enqueue(&q2, 15);
    enqueue(&q2, 25);
    enqueue(&q2, 35);
    enqueue(&q2, 45);
    enqueue(&q2, 55);
    enqueue(&q2, 65);
    enqueue(&q2, 75);
    enqueue(&q2, 85);
    enqueue(&q2, 95);
    enqueue(&q2, 105);
    enqueue(&q2, 115);
printf("queued\n");
    sortedlist(&q1, &q2, &root);
printf("sorted\n");
    printlist(root);
}

注意:

  • 在你的例子中,你得到了第4到第7个元素,即我在这里使用的索引3到6。
  • 这段代码应该适用于任何容器,而不仅仅是矢量。
  • spans是C++ Core Guidelines的GSL支持库的一部分。他们可能会在2020年正式进入C ++标准,并受到社区的青睐。