繁体   English   中英

将STL列表容器划分为大于value的元素和小于value的元素

[英]Dividing an STL list container to elements greater than value and elements lower than value

我正在制作一个函数,该函数将一个列表和一个值K接收为参数,该函数应将列表分为第一部分和第二部分,在同一列表中,而不使用另一个容器,该容器包含的值小于K,第二个元素部分包含的元素大于或等于K,这是我的尝试:

template <class T> 
void dividie_list(list<T> & mylist, T k){
    list<int>::iterator it;

    it = mylist.begin();
    while(it != mylist.end()){
        if(*it >= k){
            mylist.push_back(*it);
            it = mylist.erase(it);
        }
        else
            ++it;
    }   
}

输入输出示例:

Input : mylist={1,3,4,14,11,9,7,16,25,19,7,8,9 } y k=8  
Output: {1, 3, 4, 7, 7,9, 11, 16, 25, 19, 14, 8, 9}  

似乎该函数陷入无限循环并且没有结束,我无法弄清楚,期末考试很亲密,热心帮助。

编辑:我根据建议的解决方案尝试了其他方法,但我不能确定它是否有效,有人可以确认它:

template <class T>
 void dividie_list(list<T> & mylist, T k)
{
    typename list<T>::iterator first = mylist.begin();
    typename list<T>::iterator last = mylist.end();

    --last;

    while(first != last){
    if(*first >= k){
        swap(*first,*last);
        --last;
    }
    else
        ++first;
    }
}

如果要实现该方法而不是调用函数来完成工作,则根据此页面上的代码,这就是您想要的。

#include <list>
#include <algorithm>
#include <iostream>

using namespace std;

template <class T>
void dividie_list(list<T> & mylist, T k)
{
    typename list<T>::iterator first = mylist.begin();
    typename list<T>::iterator last = mylist.end();

    while (first!=last) 
    {
        while (*first < k)
        {
            ++first;
            if (first==last) return;
        }
        do
        {
            --last;
            if (first==last) return;
        } while (!(*last < k));

        swap (*first,*last);
        ++first;
    }

    return ;
}

驱动程序测试以上功能:

int main()
{
    int a[] = {1,3,4,14,11,9,7,16,25,19,7,8,9 };
    list<int> l(a, a + sizeof(a) / sizeof(int) );

    copy(l.begin(), l.end(), ostream_iterator<int>(cout, ", ") );
    cout<<'\n';
    dividie_list(l, 8);
    copy(l.begin(), l.end(), ostream_iterator<int>(cout, ", ") );
}

输出如下:

1, 3, 4, 14, 11, 9, 7, 16, 25, 19, 7, 8, 9,
1, 3, 4, 8, 7, 7, 9, 16, 25, 19, 11, 14, 9,

您需要返回一个迭代器而不是void以便您可以知道第一部分和第二部分之间的边界在哪里。

无需在任何地方推送或弹出项目。 仅需要枚举列表和交换元素。

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <list>

// iterator based parition implementation.
template<typename Iter>
Iter divide_list(Iter begin, Iter end,
     const typename std::iterator_traits<Iter>::value_type& val)
{
    Iter p = begin;
    for (Iter it = begin; it != end; ++it)
    {
        if (*it < val)
        {
            if (it != p)
            {
                std::cout << "Swapping " << *it << " and " << *p << '\n';
                std::iter_swap(it, p);
            }
            ++p;
        }
    }
    return p;
}

// generic container wrapper
template<template<typename, typename...> class V, typename T, typename... Args>
void divide_list(V<T,Args...>& seq, const T& arg)
{
    divide_list(std::begin(seq), std::end(seq), arg);
}

int main()
{
    std::list<int> lst { {1,3,4,14,11,9,7,16,25,19,7,8,9 } };

    for (auto x : lst)
        std::cout << x << ' ';
    std::cout << std::endl;

    divide_list(lst, 8);

    for (auto x : lst)
        std::cout << x << ' ';
    std::cout << '\n' << std::endl;

    // also works with vector (and deque)
    std::vector<int> vec { {6,4,9,14,11,2,7,9,25,16,7,8,3 } };

    for (auto x : vec)
        std::cout << x << ' ';
    std::cout << std::endl;

    divide_list(vec, 8);

    for (auto x : vec)
        std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

产量

1 3 4 14 11 9 7 16 25 19 7 8 9 
Swapping 7 and 14
Swapping 7 and 11
1 3 4 7 7 9 14 16 25 19 11 8 9 

6 4 9 14 11 2 7 9 25 16 7 8 3 
Swapping 2 and 9
Swapping 7 and 14
Swapping 7 and 11
Swapping 3 and 9
6 4 2 7 7 3 14 9 25 16 11 8 9 

另外,我修改了迭代器算法以将迭代器位置p作为函数结果返回,从而知道结果序列中的第一个元素大于或等于测试值(可能派上用场)。 这使您可以具有低序的开始/结束( lst.begin(), p )和高序的开始/结束( p, lst.end() )。 通用容器的支持仅仅是因为我很无聊。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM