Home > Mobile >  Delete the selected item in forward_list C
Delete the selected item in forward_list C

Time:04-11

I need to somehow remove an element in a list if it is already in another list. I created a function but it doesn't work. Tell me how to fix it. thank you very much.

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);
            }

        }
    }
}

CodePudding user response:

It seems you are trying to remove elements from list_2 that are found in list_1. But in this statement

l_front_2 = list_2.erase_after(l_front);

you are using the iterator l_front from list_1 that does not make a sense.

Also if an element in list_2 is removed then due to the expression j in the for loop

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

the next element in the list will be skipped.

A straightforward approach can look for example the following way as it is shown in the demonstration program below.

#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';
}

The program output is

A B A C D B E
C D E

A much more simple function definition can be if to use the method remove_if or the general function std::erase_if introduced in the C 20 Standard. For example

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 );
}

Or if the compiler supports C 20 then

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 );
}

The both presented functions remove elements in list_1 that are found in list_2.

  • Related