根据条件将元素从一个forward_list转移到另一个

Transfer elements from one forward_list to another based on condition

本文关键字:forward 一个 list 转移 另一个 条件 元素      更新时间:2023-10-16

我有两个forward_list:list1list2。我想对第一个元素进行迭代,并根据条件将元素转移到第二个元素。这里有一个使用forward_list<int>的例子,它不起作用,但我认为它表达了我想要的东西。

#include <iostream>
#include <forward_list>
using namespace std;
int main(void)
{
    forward_list<int> list1 = {1, 2, 3, 4, 5, 6};
    forward_list<int> list2;
    //Transfer elements between 2 and 5 from list1 to list2.    
    forward_list<int>::const_iterator iter_before = list1.before_begin();
    forward_list<int>::const_iterator iter = list1.begin();
    while ( iter != list1.end())
    {
        int item = *iter;
        cout << item ;
        if (2 <= item && item <= 5 )
        {
            list2.splice_after(list2.before_begin(),list1,iter_before);
            iter_before = iter;
            iter++;
            cout << "! "; // Indicates if current item is transferred.
        }
        else
        {
            iter++;
            iter_before++;
            cout << " ";
        }
    }
    cout << "nList 1: ";
    for (auto item : list1)
    {
        cout << item << " ";
    }
    cout << "nList 2: ";
    for (auto item : list2)
    {
        cout << item << " ";
    }
    cout << endl;
    return 0;
}

我已经尝试将iteriter_before迭代器重置到list1的开头,它可以工作,但会多次遍历一些list1元素(重新启动)。我还尝试过先将元素复制到list2中,然后擦除list1上的元素,这也很有效。我认为这两种解决方案都效率低下。

有人能提出一个更有效的方法吗?只需要交换列表中的指针?

诀窍在于实现:

  1. 您需要为将要拼接到另一个列表中的元素后面的元素获取迭代器,并且这必须在拼接之前进行。在拼接之后,这个迭代器将指向下一个要处理的元素
  2. 拼接后,iter_before仍然指向要处理的下一个元素之前——没有必要更改它

因此,在您的if中,改为:

auto iter_next = std::next(iter);
list2.splice_after(list2.before_begin(),list1,iter_before);
iter = iter_next;

演示。

您的答案准确地描述了STL copy_if的用例(http://www.cplusplus.com/reference/algorithm/copy_if/)。