std::映射的键的部分匹配
Partial match for the key of a std::map
我有一个std::map
,我想使用子字符串搜索键。例如,我有以下代码:
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef std::map<std::string, std::string> TStrStrMap;
typedef std::pair<std::string, std::string> TStrStrPair;
int main(int argc, char *argv[])
{
TStrStrMap tMap;
tMap.insert(TStrStrPair("John", "AA"));
tMap.insert(TStrStrPair("Mary", "BBB"));
tMap.insert(TStrStrPair("Mother", "A"));
tMap.insert(TStrStrPair("Marlon", "C"));
return 0;
}
现在,如果"Marla"存储在地图中,我想搜索包含子字符串"Marl"而不是"Marlon"的位置。我想找一些以"马尔"开头的东西。我最多需要找一个职位。这可能吗?如果是,如何?
我不想使用任何Boost库!
您不能有效地搜索子字符串,但可以搜索前缀:
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
typedef map<string, string> TStrStrMap;
typedef pair<string, string> TStrStrPair;
TStrStrMap::const_iterator FindPrefix(const TStrStrMap& map, const string& search_for) {
TStrStrMap::const_iterator i = map.lower_bound(search_for);
if (i != map.end()) {
const string& key = i->first;
if (key.compare(0, search_for.size(), search_for) == 0) // Really a prefix?
return i;
}
return map.end();
}
void Test(const TStrStrMap& map, const string& search_for) {
cout << search_for;
auto i = FindPrefix(map, search_for);
if (i != map.end())
cout << 't' << i->first << ", " << i->second;
cout << endl;
}
int main(int argc, char *argv[])
{
TStrStrMap tMap;
tMap.insert(TStrStrPair("John", "AA"));
tMap.insert(TStrStrPair("Mary", "BBB"));
tMap.insert(TStrStrPair("Mother", "A"));
tMap.insert(TStrStrPair("Marlon", "C"));
Test(tMap, "Marl");
Test(tMap, "Mo");
Test(tMap, "ther");
Test(tMap, "Mad");
Test(tMap, "Mom");
Test(tMap, "Perr");
Test(tMap, "Jo");
return 0;
}
此打印:
Marl Marlon, C
Mo Mother, A
ther
Mad
Mom
Perr
Jo John, AA
当您的子字符串是前缀时,您可以使用lower_bound
来搜索"Marl"
。
map<string,string>::const_iterator m = tMap.lower_bound("Marl");
cerr << (*m).second << endl;
这不适用于非前缀子字符串:在一般情况下,搜索映射与搜索其他容器没有太大区别。
我想通过使用map::lower_bound()
提供完整的解决方案来扩展Sergey的答案。正如对该答案的评论中所提到的,您必须检查lower_bound()
是否返回tMap.end()
。如果没有,那么您还必须检查找到的关键字是否真的以搜索字符串为前缀。后者可以通过使用string::compare()
进行检查。因此,我的C++11解决方案如下所示:
std::map<std::string, std::string> myMap{
{"John", "AA"}, {"Mary", "BBB"}, {"Mother", "A"}, {"Marlon", "C"}, {"Marla", "D"}
};
std::string prefix("Marl");
auto it = myMap.lower_bound(prefix);
if (it != std::end(myMap) && it->first.compare(0, prefix.size(), prefix) == 0)
std::cout << it->first << ": " << it->second << std::endl;
输出:
Marla:D
然而,如果你想在地图中找到所有以搜索字符串为前缀的键,那么你可以使用以下循环:
for (auto it = myMap.lower_bound(prefix); it != std::end(myMap) && it->first.compare(0, prefix.size(), prefix) == 0; ++it)
std::cout << it->first << ": " << it->second << std::endl;
输出:
Marla:D
Marlon:C
Ideone 上的代码
要在映射中搜索键的子串,您别无选择,只能在特殊类型的键上使用新映射,或者在O(n)中搜索映射。std::map
使用(默认情况下)operator<()
对关键字进行排序和搜索,而std::string
的比较函数是一个简单的字典比较。
如果在具有基于子字符串的operator<()
比较的特殊键类型上创建新映射,请注意,这也会影响要插入的新元素是否重复的决定。换句话说,这样的映射将只具有不是彼此子串的元素。
O(n)搜索实际上意味着在映射上使用std::find()
,带有一个接受std::pair<std::string,std::string>
的自定义谓词,如果对中的第二个元素是第一个元素的子字符串,则返回true。
typedef TStrStrMap::value_type map_value_type;
struct key_contains_substring
: std::binary_function<map_value_type, std::string, bool>
{
bool operator()(const map_value_type& map_value, const std::string& substr)
{
return std::search(map_value.first.begin(), map_value.first.end(),
substr.begin(), substr.end()) != map_value.first.end();
}
};
...
TStrStrMap::const_iterator it = std::find_if(tMap.begin(), tMap.end(),
std::bind2nd(key_contains_substring(), "Marl");
- 使用std::函数映射对象方法
- 使用"std::unordereded_map"映射到"std::list"对象
- C++匿名结构作为std::映射值
- 如何从存储在std::映射中的std::集中删除元素
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 当键值是 std 向量时,为什么使用 at in C++ 访问映射值如此缓慢?
- tao_idl -Gstl 不映射 std::string
- <char> 使用 Vulkan 映射内存时如何使用 std::vector 而不是 void**?
- 附加使用 Struct 作为"multikey"并将 std::vector 用作映射值的映射
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- 如何初始化 std::向量的映射?
- 如何将不同的函数签名映射到同一个 std::map?
- 从匿名命名空间映射的辅助值抛出 std::bad_alloc
- 将唯一指针插入std::映射
- C++ODB数据库映射程序:无法在关系中使用std::weak_ptr
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- std::int 和 struct 内存不足的映射 (std::Bad_alloc) c++
- 编译器不推导模板参数(映射std::vector->std::vector)