C++ 切片向量

C++ 切片向量,c++,stl,C++,Stl,我有一个std::向量。我想创建表示向量片段的迭代器。我该怎么做?在伪C++中: class InterestingType; void doSomething(slice& s) { for (slice::iterator i = s.begin(); i != s.end(); ++i) { std::cout << *i << endl; } } int main() { std::vector v(); for

我有一个std::向量。我想创建表示向量片段的迭代器。我该怎么做?在伪C++中:

class InterestingType;

void doSomething(slice& s) {
    for (slice::iterator i = s.begin(); i != s.end(); ++i) {
       std::cout << *i << endl;
    }
}
int main() {
   std::vector v();
   for (int i= 0; i < 10; ++i) { v.push_back(i); }
   slice slice1 = slice(v, 1, 5);
   slice slice2 = slice(v, 2, 4);
   doSomething(slice1);
   doSomething(slice2);
   return 0;
}
类兴趣类型;
无效剂量测定(切片和s){
对于(切片::迭代器i=s.begin();i!=s.end();++i){

std::cout您可以用一对迭代器表示这些“切片”。

您只需使用一对迭代器:

typedef std::vector<int>::iterator vec_iter;

void doSomething(vec_iter first, vec_iter last) {
    for (vec_iter cur = first; cur != last; ++cur) {
       std::cout << *cur << endl;
    }
}

int main() {
   std::vector v();
   for (int i= 0; i < 10; ++i) { v.push_back(i); }

   doSomething(v.begin() + 1, v.begin() + 5);
   doSomething(v.begin() + 2, v.begin() + 4);
   return 0;
}
typedef std::vector::iterator vec_iter;
无效剂量测量(先进行vec\u iter,后进行vec\u iter){
对于(向量cur=第一;cur!=最后;++cur){

正如其他人所说,您可以将“切片”表示为一对迭代器。如果您愿意使用Boost,您可以使用范围概念。然后您甚至可以使用begin()/end()成员函数可用,整个东西看起来就像容器。

在学习C++之前,我学习了Python。我想知道C++是否提供了像Python列表中的切片那样的向量切片。用了几分钟的时间编写这个函数,可以让它像在Python中那样完成一个向量的切片。
vector<int> slice(const vector<int>& v, int start=0, int end=-1) {
    int oldlen = v.size();
    int newlen;

    if (end == -1 or end >= oldlen){
        newlen = oldlen-start;
    } else {
        newlen = end-start;
    }

    vector<int> nv(newlen);

    for (int i=0; i<newlen; i++) {
        nv[i] = v[start+i];
    }
    return nv;
}
向量切片(常量向量&v,int start=0,int end=-1){
int oldlen=v.size();
内纽伦;
如果(结束==-1或结束>=oldlen){
newlen=oldlen开始;
}否则{
newlen=结束-开始;
}
矢量nv(newlen);

对于(int i=0;i使用增压范围适配器。它们是:

运算符|()用于惰性地添加新行为,并且从不修改其属性 左派论点

doSomething
需要将范围作为输入。一个简单的(可能是lambda)包装器可以解决这个问题。

取自:


对向量进行切片不需要一对迭代器。三个索引就可以了,因为它允许您通过以下步骤创建切片:

static const int arr[] = {16,2,77,29,42};
vector<int> v (arr, arr + sizeof(arr) / sizeof(arr[0]) );
vector<int>::iterator i;
const int step = 2;
const int first = 0;
const int last = v.size()-1;
int counter=first;
for (i = v.begin()+first; counter<last; i+=step, counter+=step) {
    // Do something with *i
    cout << *i << endl;
}

在这段代码中,需要一个计数器来跟踪位置,因为不是所有迭代器都能做到这一点。

可以将切片与
std::valarray
一起使用。这是python中
numpy.array
的STL模拟。它支持不同的向量化操作,如min、max、+、-、*、/,等等。 更多信息

std::slice(开始、长度、跨步)
允许选择和修改数组的切片,而无需复制(文档)

切片将如下所示:

  std::valarray<int> foo (9);
  for (int i=0; i<9; ++i) foo[i]=i;         //  0  1  2  3  4  5  6  7  8
                                            //     |  |  |  |  |
  std::slice myslice=std::slice(1,5,1);     //     v  v  v  v  v
  foo[myslice] *= std::valarray<int>(10,3); //  0 10 20 30 40 50  6  7  8

为什么这是社区维基?当你需要一个范围和一个不等于一的跨距时,它通常被称为“切片”。例如,请参阅std::gslice和std::valarray。跨距为一时,它通常被称为“范围”。我会编写“两个迭代器参数”iso迭代器对(std::pair)。这不适用于跨距(步骤)Python的切片还有一个可选的第三个参数,与range()类似是反转字符串或列表的一种快速简便的方法。大多数语言中切片的美妙之处在于,无需复制操作即可获得子向量/字符串。您的示例逐元素复制数据元素。但如果您不关心alloc或复制速度,则可以。不要使用此函数。没有理由只为vect使用特殊函数ORS;至少将它推广到任何容器。和其他人一样建议通过一个范围(是的,我知道C++没有范围。但是它很快就会足够,这个评论仍然在这里。)在C++中,你需要创建一个结构,它为切片保存迭代器的开始和结束。
std::vector<myvector::value_type>(myvector.begin()+start, myvector.begin()+end).swap(myvector);
#include <iostream>
#include <vector>

int main ()
{
    std::vector<int> indexes{3, 6, 9};

    for( auto index : indexes )
    {
        int slice = 3;
        std::vector<int> bar{1, 2, 3, 4, 5, 6, 7, 8, 9};
        std::vector<int>( bar.begin() + index - slice, bar.begin() + index ).swap(bar);

        std::cout << "bar index " << index << " contains:";
        for (unsigned i=0; i<bar.size(); i++)
            std::cout << ' ' << bar[i];
        std::cout << '\n';
    }

    return 0;
}
bar index 3 contains: 1 2 3
bar index 6 contains: 4 5 6
bar index 9 contains: 7 8 9
static const int arr[] = {16,2,77,29,42};
vector<int> v (arr, arr + sizeof(arr) / sizeof(arr[0]) );
vector<int>::iterator i;
const int step = 2;
const int first = 0;
const int last = v.size()-1;
int counter=first;
for (i = v.begin()+first; counter<last; i+=step, counter+=step) {
    // Do something with *i
    cout << *i << endl;
}
16
77
  std::valarray<int> foo (9);
  for (int i=0; i<9; ++i) foo[i]=i;         //  0  1  2  3  4  5  6  7  8
                                            //     |  |  |  |  |
  std::slice myslice=std::slice(1,5,1);     //     v  v  v  v  v
  foo[myslice] *= std::valarray<int>(10,3); //  0 10 20 30 40 50  6  7  8
  std::valarray<int> foo (9);
  for (int i=0; i<9; ++i) foo[i]=i;         //  0  1  2  3  4  5  6  7  8
                                            //     |     |     |
  std::slice myslice=std::slice(1,3,2);     //     v     v     v
  foo[myslice] *= std::valarray<int>(10,3); //  0 10  2 30  4 50  6  7  8
                                            //  |        |        |
  foo[std::slice (0,3,3)] = 99;             //  v        v        v
                                            // 99 10  2 99  4 50 99  7  8
  std::cout << "foo:";
  for (std::size_t n=0; n<foo.size(); n++)
      std::cout << ' ' << foo[n];
  std::cout << '\n';