在 forward_list C++ 中删除所选项目

Delete the selected item in forward_list C++

如果列表中的某个元素已经在另一个列表中,我需要以某种方式删除该元素。我创建了一个函数,但它不起作用。告诉我如何解决它。非常感谢。

void compare(forward_list<string> list_1, forward_list<string> list_2) {

    auto prev = list_1.before_begin();

    for (int i = 0; i < Size(list_1); i++) {

        auto l_front = list_1.begin();
        advance(l_front, i);
        
        for (int j = 0; j < Size(list_2); j++) {

            auto l_front_2 = list_2.begin();
            advance(l_front_2, j);
            if (*l_front == *l_front_2)
            {
                l_front_2 = list_2.erase_after(l_front);
            }

        }
    }
}

您似乎正试图从 list_2 中删除在 list_1 中找到的元素。但是在这个声明中

l_front_2 = list_2.erase_after(l_front);

您正在使用 list_1 中的迭代器 l_front,这没有任何意义。

此外,如果 list_2 中的元素被删除,则由于 for 循环中的表达式 j++

for (int j = 0; j < Size(list_2); j++) {

将跳过列表中的下一个元素。

一个简单的方法可以看下面的演示程序中所示的方式。

#include <iostream>
#include <string>
#include <forward_list>
#include <iterator>
#include <algorithm>

void make_unique( std::forward_list<std::string> &list_1,
    const std::forward_list<std::string> &list_2 )
{
    for ( auto current = std::begin( list_1 ); current != std::end( list_1 ); )
    {
        if (std::find( std::begin( list_2 ), std::end( list_2 ), *current ) != std::end( list_2 ))
        {
            std::string s( *current );
            list_1.remove( s );
            current = std::begin( list_1 );
        }
        else
        {
            std::advance( current, 1 );
        }
    }
}

int main()
{
    std::forward_list<std::string> list_1 = { "A", "B", "A", "C", "D", "B", "E" };
    std::forward_list<std::string> list_2 = { "A", "B" };

    for (const auto &s : list_1)
    {
        std::cout << s << ' ';
    }
    std::cout << '\n';

    make_unique( list_1, list_2 );

    for (const auto &s : list_1)
    {
        std::cout << s << ' ';
    }
    std::cout << '\n';
}

程序输出为

A B A C D B E
C D E

如果使用 C++ 20 标准中引入的方法 remove_if 或通用函数 std::erase_if,则可以定义更简单的函数。例如

void make_unique( std::forward_list<std::string> &list_1,
    const std::forward_list<std::string> &list_2 )
{
    auto found = [&list_2]( const auto &s )
    {
        return std::find( std::begin( list_2 ), std::end( list_2 ), s ) != std::end( list_2 );
    };

    list_1.remove_if( found );
}

或者如果编译器支持 C++ 20 那么

void make_unique( std::forward_list<std::string> &list_1,
    const std::forward_list<std::string> &list_2 )
{
    auto found = [&list_2]( const auto &s )
    {
        return std::find( std::begin( list_2 ), std::end( list_2 ), s ) != std::end( list_2 );
    };

    std::erase_if( list_1, found );
}

这两个函数都删除了 list_1 中的元素,这些元素在 list_2 中找到。