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
.