[英]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.