我正在创建一个函数,作为参数接收列表和值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;
}
}
答案 0 :(得分:1)
如果您想要实现该方法而不是调用函数来完成工作,那么根据代码on this page,这就是您想要的。
#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
,以便您可以知道第一部分和第二部分之间的边界。
答案 1 :(得分:1)
无需在任何地方推送或弹出物品。只需按需要枚举列表和交换元素即可。
#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()
)的开始/结束。通用容器支持完全是因为我很无聊。