Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于条件拆分STL列表_C++_Algorithm_List_Vector_Stl - Fatal编程技术网

C++ 基于条件拆分STL列表

C++ 基于条件拆分STL列表,c++,algorithm,list,vector,stl,C++,Algorithm,List,Vector,Stl,我有一个std::列表,如下所示(x标记表示一些小于500的数字) 我现时的守则如下: list<int> templist; vector<list<int> > v; for(list<int>::iterator lit=originallist.begin(); lit!=oriniallist.end(); ++lit) { if (*lit > 500) { templist.push_back(*lit)

我有一个std::列表,如下所示(x标记表示一些小于500的数字)

我现时的守则如下:

list<int> templist; vector<list<int> > v;
for(list<int>::iterator lit=originallist.begin(); lit!=oriniallist.end(); ++lit) {
    if (*lit > 500) {
        templist.push_back(*lit);v.push_back(templist); templist.clear(); continue;
    }
    templist.push_back(*lit);
}
列表模板;向量v;
对于(列表::迭代器lit=originallist.begin();lit!=oriniallist.end();++lit){
如果(*点亮>500){
templast.push_back(*亮);v.push_back(templast);templast.clear();continue;
}
圣殿骑士。推回(*亮);
}
<>在没有使用TEPLPLIST的情况下,C++中实现以上任务的最有效方法是什么?非常感谢您的帮助。

请尝试以下方法

#include <vector>
#include <list>
#include <algorithm>
#include <functional>

//...

auto first = YourList.begin();

while ( first != YourList.end() )
{
   auto last = std::find_if( first, YourList.end(), std::bind2nd( std::greater<int>(), 500 ) );
   if ( last != YourList.end() ) ++last;

   YourVector.push_back( std::list<int>( first, last ) );

   first = last;
} 
#包括
#包括
#包括
#包括
//...
auto first=YourList.begin();
while(first!=YourList.end())
{
auto last=std::find_if(首先,YourList.end(),std::bind2nd(std::greater(),500));
如果(last!=YourList.end())+last;
YourVector.push_back(std::list(first,last));
第一个=最后一个;
} 
  • 循环浏览这些数字,并获得需要拆分列表的位置之间的距离

  • 对每个拆分位置使用列表中的拼接功能:

    lst.splice( newLst.begin(), newLst, lst.begin(), lst.begin() + sliceLength);
    

  • (请注意,拼接将破坏原始列表)

    第三版 此版本使用
    std::list::splice
    并移动迭代器,直到找到iter或到达iter

    #include <iostream>
    #include <list>
    #include <vector>
    
    std::vector< std::list<int> > & split( std::list<int>  v,
                       int delim, std::vector< std::list<int> >& elems) {
    
        auto it = v.begin();
    
        while ( it != v.end()) {
            std::list<int> l;
    
            while ( it != v.end() && *it < delim) {
                ++it;
            }
    
            if( it != v.end()) {
                l.splice( l.begin(), v, v.begin(), ++it);
                it = v.begin();
            } else {
                l.splice( l.begin(), v, v.begin(), it);
            }
    
            elems.push_back( l);
        }
        return elems;
    }
    
    
    std::vector< std::list<int> > split( const std::list<int>  &v, int delim) {
        std::vector< std::list<int> > elems;
        split( v, delim, elems);
        return elems;
    }
    
    用法:

    int main() {
    
        std::list<int> v = { 1, 2, 3, 503, 5, 6, 502, 7, 510, 3, 500, 6, 7};
        std::vector< std::list<int> > vl;
        vl = split( v, 500);
    
        int i = 0;
        while( i < vl.size()) {
            std::list<int>::const_iterator it = vl[ i].begin();
            while( it !=  vl[ i].end())
                std::cout << *it++;
            std::cout << std::endl;
            ++i;
        }
    
        return 0;
    }
    
    int main() {
    
        std::list<int> v = { 1, 2, 3, 503, 5, 6, 502, 7, 510, 3, 500, 5, 9};
        std::vector< std::list<int> > vl;
        vl = split( v, 500);
    
        int i = 0;
        while( i < vl.size()) {
            std::list<int>::const_iterator it = vl[ i].begin();
            while( it !=  vl[ i].end())
                std::cout << *it++;
            ++i;
        }
    
        return 0;
    }
    
    int main() {
    
        std::list<int> v = { 1, 2, 3, 503, 5, 6, 502, 7, 510, 3, 500, 5, 9};
        std::vector< std::list<int> > vl;
        vl = split( v, 500);
    
        int i = 0;
        while( i < vl.size()) {
    
            std::list<int>::const_iterator it = vl[ i].begin();
    
            while( it !=  vl[ i].end())
                std::cout << *it++;
    
            ++i;
        }
    
        return 0;
    }
    
    用法:

    int main() {
    
        std::list<int> v = { 1, 2, 3, 503, 5, 6, 502, 7, 510, 3, 500, 6, 7};
        std::vector< std::list<int> > vl;
        vl = split( v, 500);
    
        int i = 0;
        while( i < vl.size()) {
            std::list<int>::const_iterator it = vl[ i].begin();
            while( it !=  vl[ i].end())
                std::cout << *it++;
            std::cout << std::endl;
            ++i;
        }
    
        return 0;
    }
    
    int main() {
    
        std::list<int> v = { 1, 2, 3, 503, 5, 6, 502, 7, 510, 3, 500, 5, 9};
        std::vector< std::list<int> > vl;
        vl = split( v, 500);
    
        int i = 0;
        while( i < vl.size()) {
            std::list<int>::const_iterator it = vl[ i].begin();
            while( it !=  vl[ i].end())
                std::cout << *it++;
            ++i;
        }
    
        return 0;
    }
    
    int main() {
    
        std::list<int> v = { 1, 2, 3, 503, 5, 6, 502, 7, 510, 3, 500, 5, 9};
        std::vector< std::list<int> > vl;
        vl = split( v, 500);
    
        int i = 0;
        while( i < vl.size()) {
    
            std::list<int>::const_iterator it = vl[ i].begin();
    
            while( it !=  vl[ i].end())
                std::cout << *it++;
    
            ++i;
        }
    
        return 0;
    }
    
    intmain(){
    列表v={1,2,3503,5,6502,7510,3500,5,9};
    std::vectorvl;
    vl=分裂(v,500);
    int i=0;
    而(istd::cout虽然此解决方案使用临时的
    std::list
    ,但它不分配列表节点元素,在C++03情况下只分配1个内存(C++11情况根据返回值的大小分配对数个内存)

    这是一个C++03解决方案。一个C++11解决方案可以一次性完成

    bool big_as_500( int x ) {return x>=500;}
    
    std::vector< std::list< int > > do_stuff( std::list<int>& original_list ) {
      // we have to do this, because resizing the return value involves lots of allocations
      // and stuff in C++03, so make sure we get the size right by precalculating it:
      std::size_t count = std::count_if( originallist.begin(), originallist.end(), big_as_500 );
      std::vector< std::list< int > > result;
      result.reserve(count+1); 
    
      typedef std::list<int>::const_iterator const_iterator;
      std::list< int > current;
      for(const_iterator it= originallist.begin(); it!=originallist.end();/*nothing*/) {
        ++it; // about to invalidate it! (or move lists)
        current.splice( current.end(), originallist, originallist.begin() ); // O(1) no memory allocation
        if (big_as_500(current.back())) {
          result.push_back( std::list<int>() );
          current.swap( result.back() );
        }
      }
      // original problem does not specify what to do if the original list does not end
      // with an element "big_as_500", so I'll just drop them
      return result; // rely on NRVO to eliminate the copy here, if your compiler does not
      // support it, take result as a reference parameter.
    }
    
    template<typename T, typename A>
    void efficient_grow_by_1( std::vector<T,A>& make_one_bigger ) {
      if (make_one_bigger.size()+1 > make_one_bigger.capacity() )
      {
        std::vector<T, A> swap_vec;
        swap_vec.reserve( (make_one_bigger.size()+1)*5/3 );
        for (std::vector<T, A>::iterator it = make_one_bigger.begin(); it != make_one_bigger.end(); ++it ) {
          using std::swap;
          swap_vec.push_back();
          std::swap( *it, swap_vec.back() );
        }
        swap_vec.swap( make_one_bigger );
      }
      make_one_bigger.push_back();
    }
    void do_stuff( std::list<int>& original_list, std::vector< std::list< int > >& result ) {
      typedef std::list<int>::const_iterator const_iterator;
      std::list< int > current;
      for(const_iterator it= originallist.begin(); it!=originallist.end();) {
        ++it;
        current.splice( current.end(), originallist, originallist.begin() ); // O(1) no memory allocation
        if (current.back()>=500) {
          efficient_grow_by_1(result);
          current.swap( result.back() );
        }
      }
      // original problem does not specify what to do if the original list does not end
      // with an element "big_as_500", so I'll just drop them
    }
    
    bool big_as_500(int x){return x>=500;}
    std::vector>做些什么(std::list和原始列表){
    //我们必须这样做,因为调整返回值需要大量的分配
    //C++03中的内容,因此请确保通过预先计算得到正确的大小:
    std::size\u t count=std::count\u if(originalist.begin()、originalist.end()、big\u as\u 500);
    std::vector>结果;
    结果:储备(计数+1);
    typedef std::list::const_迭代器const_迭代器;
    标准::列表当前;
    for(const_iterator it=originallist.begin();it!=originallist.end();/*nothing*/){
    ++it;//即将使其无效!(或移动列表)
    current.splice(current.end(),originallist,originallist.begin());//O(1)没有内存分配
    if(大的作为500(current.back())){
    result.push_back(std::list());
    current.swap(result.back());
    }
    }
    //原始问题没有指定如果原始列表没有结束该怎么办
    //有一个元素“big_as_500”,所以我就把它们扔了
    return result;//如果编译器不执行此操作,请依赖NRVO消除此处的副本
    //支持它,将结果作为参考参数。
    }
    
    C++11解决方案:

    std::vector< std::list< int > > do_stuff( std::list<int>& original_list ) {
      std::vector< std::list< int > > result;
    
      typedef std::list<int>::const_iterator const_iterator;
      std::list< int > current;
      for(const_iterator it= originallist.begin(); it!=originallist.end();/*nothing*/) {
        ++it;// about to become invalid/in wrong list
        current.splice( current.end(), originallist, originallist.begin() ); // O(1) no memory allocation
        if (current.back() >= 500) {
          result.emplace_back( std::move(current) );
        }
      }
      // original problem does not specify what to do if the original list does not end
      // with an element "big_as_500", so I'll just drop them
      return result; // will NRVO, or move, so no worries
    }
    
    std::vector>do_stuff(std::list和原始_列表){
    std::vector>结果;
    typedef std::list::const_迭代器const_迭代器;
    标准::列表当前;
    for(const_iterator it=originallist.begin();it!=originallist.end();/*nothing*/){
    ++它;//即将失效/在错误列表中
    current.splice(current.end(),originallist,originallist.begin());//O(1)没有内存分配
    if(current.back()>=500){
    结果:向后放置(标准::移动(当前));
    }
    }
    //原始问题没有指定如果原始列表没有结束该怎么办
    //有一个元素“big_as_500”,所以我就把它们扔了
    返回结果;//将NRVO或move,因此无需担心
    }
    
    在C++11中,调整大小相对便宜,所以我们很好

    现在,我们可以非常喜欢C++03,并模仿C++11的功能,一次完成所有工作

    bool big_as_500( int x ) {return x>=500;}
    
    std::vector< std::list< int > > do_stuff( std::list<int>& original_list ) {
      // we have to do this, because resizing the return value involves lots of allocations
      // and stuff in C++03, so make sure we get the size right by precalculating it:
      std::size_t count = std::count_if( originallist.begin(), originallist.end(), big_as_500 );
      std::vector< std::list< int > > result;
      result.reserve(count+1); 
    
      typedef std::list<int>::const_iterator const_iterator;
      std::list< int > current;
      for(const_iterator it= originallist.begin(); it!=originallist.end();/*nothing*/) {
        ++it; // about to invalidate it! (or move lists)
        current.splice( current.end(), originallist, originallist.begin() ); // O(1) no memory allocation
        if (big_as_500(current.back())) {
          result.push_back( std::list<int>() );
          current.swap( result.back() );
        }
      }
      // original problem does not specify what to do if the original list does not end
      // with an element "big_as_500", so I'll just drop them
      return result; // rely on NRVO to eliminate the copy here, if your compiler does not
      // support it, take result as a reference parameter.
    }
    
    template<typename T, typename A>
    void efficient_grow_by_1( std::vector<T,A>& make_one_bigger ) {
      if (make_one_bigger.size()+1 > make_one_bigger.capacity() )
      {
        std::vector<T, A> swap_vec;
        swap_vec.reserve( (make_one_bigger.size()+1)*5/3 );
        for (std::vector<T, A>::iterator it = make_one_bigger.begin(); it != make_one_bigger.end(); ++it ) {
          using std::swap;
          swap_vec.push_back();
          std::swap( *it, swap_vec.back() );
        }
        swap_vec.swap( make_one_bigger );
      }
      make_one_bigger.push_back();
    }
    void do_stuff( std::list<int>& original_list, std::vector< std::list< int > >& result ) {
      typedef std::list<int>::const_iterator const_iterator;
      std::list< int > current;
      for(const_iterator it= originallist.begin(); it!=originallist.end();) {
        ++it;
        current.splice( current.end(), originallist, originallist.begin() ); // O(1) no memory allocation
        if (current.back()>=500) {
          efficient_grow_by_1(result);
          current.swap( result.back() );
        }
      }
      // original problem does not specify what to do if the original list does not end
      // with an element "big_as_500", so I'll just drop them
    }
    
    模板
    void-efficient按1增长(std::vector&使一个更大){
    if(make_one_bigger.size()+1>make_one_bigger.capacity())
    {
    标准::向量交换向量;
    交换向量储备((使一个更大的向量大小()+1)*5/3);
    对于(std::vector::iterator it=make_one_bigger.begin();it!=make_one_bigger.end();+it){
    使用std::swap;
    交换向量。向后推();
    std::swap(*it,swap_vec.back());
    }
    交换向量交换(使一个更大);
    }
    再大一点。把你推回去();
    }
    void do_stuff(标准::列表和原始列表,标准::向量<标准::列表>和结果){
    typedef std::list::const_迭代器const_迭代器;
    标准::列表当前;
    for(const_iterator it=originallist.begin();it!=originallist.end();){
    ++它;
    current.splice(current.end(),originallist,originallist.begin());//O(1)没有内存分配
    if(current.back()>=500){
    有效的增长率为1(结果);
    current.swap(result.back());
    }
    }
    //原始问题没有指定如果原始列表没有结束该怎么办
    //有一个元素“big_as_500”,所以我就把它们扔了
    }
    
    这太疯狂了,所以我建议升级你的编译器

    这里的诀窍是,我们用一次一个元素的
    拼接来填充“临时”列表。因为
    std::list::splice
    的(大多数?)实现最终不得不遍历元素来计数它们(这在C++11中是必需的,在C++03中是常见的),在确定要放入下一个块中的元素时,一次执行一个操作是合理有效的。每个节点直接来自输入列表,并被收集到临时列表中(无内存分配)

    一旦我们建立了这个列表,我们直接将它交换到
    列表的输出
    向量中。这避免了任何内存分配,除了我