代码之家  ›  专栏  ›  技术社区  ›  An̲̳̳drew Chad Okere

从向量中提取子向量的最佳方法?

  •  227
  • An̲̳̳drew Chad Okere  · 技术社区  · 17 年前

    std::vector (让我们称之为 myVec )大小 N . 构造由元素X到Y的副本组成的新向量的最简单方法是什么,其中0<=X<=Y<=N-1?例如 myVec [100000] myVec [100999] 以大小向量表示 150000

    如果向量不能有效地实现这一点,那么我是否应该使用另一种STL数据类型?

    13 回复  |  直到 13 年前
        1
  •  420
  •   Greg Rogers    17 年前
    vector<T>::const_iterator first = myVec.begin() + 100000;
    vector<T>::const_iterator last = myVec.begin() + 101000;
    vector<T> newVec(first, last);
    

        2
  •  97
  •   Loki Astari    17 年前

    只需使用向量构造函数。

    std::vector<int>   data();
    // Load Z elements into data so that Z > Y > X
    
    std::vector<int>   sub(&data[100000],&data[101000]);
    
        3
  •  29
  •   Dávid Tóth    6 年前

    这个讨论已经很老了,但是最简单的一个还没有被提及,有 list-initialization :

     vector<int> subvector = {big_vector.begin() + 3, big_vector.end() - 2}; 
    

    它需要c++11或更高版本。

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main(){
    
        vector<int> big_vector = {5,12,4,6,7,8,9,9,31,1,1,5,76,78,8};
        vector<int> subvector = {big_vector.begin() + 3, big_vector.end() - 2};
    
        cout << "Big vector: ";
        for_each(big_vector.begin(), big_vector.end(),[](int number){cout << number << ";";});
        cout << endl << "Subvector: ";
        for_each(subvector.begin(), subvector.end(),[](int number){cout << number << ";";});
        cout << endl;
    }
    

    结果:

    Big vector: 5;12;4;6;7;8;9;9;31;1;1;5;76;78;8;
    Subvector: 6;7;8;9;9;31;1;1;5;76;
    
        4
  •  29
  •   jackw11111    5 年前

    std::vector<T>(input_iterator, input_iterator) ,就你而言 foo = std::vector<T>(myVec.begin () + 100000, myVec.begin () + 150000); ,例如见 here

        5
  •  26
  •   einpoklum    5 年前

    现在,我们使用 span s所以你会写:

    #include <gsl/span>
    
    ...
    auto start_pos = 100000;
    auto length = 1000;
    auto span_of_myvec = gsl::make_span(myvec);
    auto my_subspan = span_of_myvec.subspan(start_pos, length);
    

    以获得1000个与相同类型的元素的跨度 myvec 是的。或者更简洁的形式:

    auto my_subspan = gsl::make_span(myvec).subspan(1000000, 1000);
    

    (但我不太喜欢这一点,因为每个数字参数的含义并不完全清楚;如果长度和起始位置的数量级相同,情况会变得更糟。)

    无论如何,记住这是 不是副本,只是一个视图

    std::vector<T> new_vec(my_subspan.cbegin(), my_subspan.cend());
    

    笔记:

        6
  •  11
  •   Salman A    17 年前

    如果两者都不需要修改(不需要添加/删除项目-只要注意线程问题,修改现有项目就可以了),您可以简单地进行传递 data.begin() + 100000 data.begin() + 101000 ,并假装他们是 begin() end() 一个较小的向量。

    T *arrayOfT = &data[0] + 100000;
    size_t arrayOfTLength = 1000;
    

        7
  •  6
  •   MasterHD    10 年前

    你没提到什么类型的 std::vector<...> myVec std::vector<type> myVec 哪里 type 在这种情况下是 int :

    typedef int type; //choose your custom type/struct/class
    int iFirst = 100000; //first index to copy
    int iLast = 101000; //last index + 1
    int iLen = iLast - iFirst;
    std::vector<type> newVec;
    newVec.resize(iLen); //pre-allocate the space needed to write the data directly
    memcpy(&newVec[0], &myVec[iFirst], iLen*sizeof(type)); //write directly to destination buffer from source buffer
    
        8
  •  5
  •   MasterAler Seema Hari    6 年前

    insert

    vector<type> myVec { n_elements };
    
    vector<type> newVec;
    
    newVec.insert(newVec.begin(), myVec.begin() + X, myVec.begin() + Y);
    
        9
  •  3
  •   Yuval F    17 年前

    你可以用 STL copy

        10
  •  1
  •   Daniel Spiewak    17 年前

    List#subseq 方法以恒定时间创建子序列。但是,只有当收集是不可变的并且底层语言使用垃圾收集时,这才有效。

        11
  •  0
  •   Community Mohan Dere    9 年前

    也许是 array_view/span 在GSL库中是一个很好的选择。

    这里还有一个单文件实现: array_view

        12
  •  0
  •   Jishu Dohare    7 年前

    轻松地将元素从一个向量复制到另一个向量

    `

    vector<pair<int, int> > v(n);
    
    //we want half of elements in vector a and another half in vector b
    vector<pair<lli, lli> > a(v.begin(),v.begin()+n/2);
    vector<pair<lli, lli> > b(v.begin()+n/2, v.end());
    
    
    //if v = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
    //then a = [(1, 2), (2, 3)]
    //and b = [(3, 4), (4, 5), (5, 6)]
    
    //if v = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]
    //then a = [(1, 2), (2, 3), (3, 4)]
    //and b = [(4, 5), (5, 6), (6, 7)]
    

    '

    vector<pair<int, int> > a(v.begin()+10, v.begin+16);
    

    若你们想要从索引10中的元素到从末尾的某个索引,那个么在这种情况下

    vector<pair<int, int> > a(v.begin()+10, v.end()-5);
    

    v.end()-5 > v.begin()+10

        13
  •  0
  •   JHBonarius    7 年前

    还有一个选择: 例如,当在 thrust::device_vector thrust::host_vector ,其中不能使用构造函数。

    std::vector<T> newVector;
    newVector.reserve(1000);
    std::copy_n(&vec[100000], 1000, std::back_inserter(newVector));
    

    也应该是O(N)

    您可以将此与顶级anwer代码结合使用

    vector<T>::const_iterator first = myVec.begin() + 100000;
    vector<T>::const_iterator last = myVec.begin() + 101000;
    std::copy(first, last, std::back_inserter(newVector));
    
        14
  •  -2
  •   mrrgu    12 年前

    只是为了其他人才这么晚才发布。我打赌第一个编码器现在已经完成了。 对于简单的数据类型,不需要复制,只需恢复到良好的旧C代码方法。

    std::vector <int>   myVec;
    int *p;
    // Add some data here and set start, then
    p=myVec.data()+start;
    

    len < myVec.size()-start