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