使用STL算法查找集合中的所有匹配项
Using STL algorithm to find all matches in a set
我有一个包含Song对象的集合。我想搜索所有出现的具有特定标题的歌曲。我被要求使用STL算法。
问题是,当它发现第一个事件时,它会停止搜索。
我正试图通过使用while循环并更改从哪里开始搜索来修复它,但我很难让它正常工作。
原始功能
set<Song> SongLibrary::SearchSong(string title)
{
set<Song> foundSongs;
find_if(begin(m_songs), end(m_songs),[&](Song const& p)
{
if (p.getTitle() == title)
{
foundSongs.insert(p);
}
return p.getTitle() == title; });
return foundSongs;
}
这是我试图将其修改为使用while循环
while (startSearch != m_songs.end)
{
find_if(startSearch, end(m_songs), [&](Song const& p) // wont take start search as a parameter
{
if (p.getTitle() == title)
{
startSearch == m_songs.Position(); // this Line is wrong
foundSongs.insert(p);
}
return p.getTitle() == title; });
}
尝试使用Copy_if
copy_if(m_songs.begin(), m_songs.end(), foundSongs, [&](Song const& s), s.getTitle() == title);
对于这样的情况,通常需要使用std::copy_if
:
set<Song> SongLibrary::SearchSong(string title)
{
set<Song> foundSongs;
std::copy_if(begin(m_songs), end(m_songs),
std::inserter(foundSongs, end(foundSongs)),
[&](Song const &s) { return s.getTitle() == title; });
}
[无关:我使用了与问题中相同的签名,但至少值得考虑通过常量引用而不是值传递参数。]
如果您将歌曲存储在序列容器中(例如,vector
或deque
),则可能会使用std::partition
:
auto pos = std::partition(begin(m_songs), end(m_songs),
[&](Song const &s) { return s.getTitle() == title; });
在这种情况下,[m_songs.begin(), pos)
是与请求匹配的歌曲范围,[pos, m_songs.end())
是不匹配的歌曲。
还要注意,set
按排序顺序存储项目。因此,如果在对集合的成员进行排序时使用getTitle()
作为关键字(或者至少是主键),您可能可以更高效地执行操作——您可以使用集合的equal_range
成员来查找所有具有相同标题的歌曲。这将为您提供具有对数复杂度的范围的开始和结束的迭代器。然后,您将复制该范围(具有线性复杂性),因此,如果您关心的范围仅占整个集合的一小部分,则这可能会大大提高速度。
不幸的是,在像copy_if
这样的函数中,不能将std::back_inserter
用于没有push_back
函数和std::set
函数的容器,但是您可以通过将其复制到向量中来实现这一点。
// Suppose i want to copy all occurrences of 1
set<int> v{1, 2, 1, 4,1, 6, 1, 1, 9, 10};
vector<int> newSet;
std::copy_if(v.begin(),v.end(),std::back_inserter(newSet),[](int val) { return val == 1;});
但是你为什么要用set
呢。从代码中看,Songs
实例似乎不应该按排序顺序存储。
除非您需要按唯一元素的排序顺序存储Songs
,否则您可以使用"vector"来实现您尝试通过进行的操作
vector<int> v{1, 2, 1, 4,1, 6, 1, 1, 9, 10};
vector<int> newSet;
std::copy_if(v.begin(),v.end(),std::back_inserter(newSet),[](int val) { return val == 1;});
- 为什么这个运算符<重载函数对 STL 算法不可见?
- STL算法函数在多个一维容器上的使用
- C++:尝试使用等效的 STL 算法消除原始循环
- STL算法和back_inserter可以预分配空间吗?
- 如何使用 STL 算法将整数向量转换为字符串向量?
- 是否有一种 STL 算法可以最后找到,但它也适用于指针?
- C++ - 如何使用<int> <int>STL 算法功能在矢量<vector>中找到矢量?
- 如何在变量容器上使用stl算法
- 在 stl 算法中移动迭代器
- 如何使用 STL 算法找到最小值和最大值?
- C STL算法相等
- 在 stl 算法中使用函数对象
- 重新定义要在字符串的 STL 算法中使用的<运算符
- 将 STL 算法与 Qt 容器结合使用
- 使用STL算法合并2个向量
- STL算法函数,如累加,如果传递给它们的函数接受引用,请避免复制
- 什么 STL 算法可以确定容器中的一个项目是否满足谓词?
- c ++ 是否有 STL 算法来检查范围是否严格排序
- begin() 和 end() 用于 STL 算法
- STL算法并嵌套以循环