C++ 映射复杂查找操作

C++ 映射复杂查找操作,c++,stl,boost,map,find,C++,Stl,Boost,Map,Find,我想做以下事情: 定义字符串和任何类型对象(可以是列表、整数或任何对象)之间的映射。 映射的键可以如下所示(值同样不重要): “AAA/123”=>1 “AAA/”==>2 “BBB/”==>3 “CCC/*”==>4 “CCC/123”=>5 现在,诀窍是,我希望在给定以下字符串的情况下找到正确的值: “AAA/123”应给出1. “AAA/111”应给出2. “CCC/111”应给出4. “CCC/123”应给出5. “BBB/AAA/123”应给出3 P> >我想知道我是如何用C++和S

我想做以下事情:
定义字符串和任何类型对象(可以是列表、整数或任何对象)之间的映射。
映射的键可以如下所示(值同样不重要):
“AAA/123”=>1
“AAA/”==>2
“BBB/”==>3
“CCC/*”==>4
“CCC/123”=>5
现在,诀窍是,我希望在给定以下字符串的情况下找到正确的值:
“AAA/123”应给出1.
“AAA/111”应给出2.
“CCC/111”应给出4.
“CCC/123”应给出5.
“BBB/AAA/123”应给出3


<> P> >我想知道我是如何用C++和STL /Boost?

< P>来的。这里是一个LITB答案的变体(它从答案列表中被删除),它可能在“*”被移除时工作:

template<typename Map> typename Map::const_iterator
find_prefix(Map const& map, typename Map::key_type const& key)
{
    typename Map::const_iterator it = map.upper_bound(key);
    while (it != map.begin())
    {
        --it;
        if(key.substr(0, it->first.size()) == it->first)
            return it;
    }

    return map.end(); // map contains no prefix
}
模板类型名映射::常量迭代器
查找前缀(映射常量和映射,类型名称映射::键类型常量和键)
{
typename Map::const\u迭代器it=Map.upper\u-bound(key);
while(it!=map.begin())
{
--它;
if(key.substr(0,it->first.size())==it->first)
归还它;
}
return map.end();//映射不包含前缀
}
我忘了添加使用它的代码:

std::map<std::string, int> smap;
smap["AAA/"] = 1;
smap["BBB/"] = 2;
smap["AAA/AA"] = 3;

find_prefix(smap, "AAA/AB")->second; // ==> 1
find_prefix(smap, "AAA/AA")->second; // ==> 3
find_prefix(smap, "BBB/AB")->second; // ==> 2
find_prefix(smap, "CCC/AB"); // ==> smap.end()
std::map smap;
smap[“AAA/”]=1;
smap[“BBB/”]=2;
smap[“AAA/AA”]=3;
查找前缀(smap,“AAA/AB”)->秒;//=>1.
查找前缀(smap,“AAA/AA”)->秒;//=>3.
查找前缀(smap,“BBB/AB”)->秒;//=>2.
查找前缀(smap,“CCC/AB”);//=>smap.end()

任何评论(感谢litb)?

从您的需求来看,您似乎并不真正想要地图数据结构,但可以设置或做一些非常简单的事情

我认为像这个std::map这样的结构可能会对您有所帮助。any将能够存储任何内容,但需要注意的是,您需要知道值类型是读回它的

键是字符串,因此它也可以是正则表达式。使用此结构,您将需要两次通过算法,如下所示:

std::map<std::string, boost::any> _map;
if (_map.find(key) != _map.end)
{
   // exact match
}
else
{
   // Have to do sequential regex (use boost::regex) matching
}
std::map\u map;
如果(_map.find(key)!=_map.end)
{
//精确匹配
}
其他的
{
//必须进行顺序正则表达式(使用boost::regex)匹配
}
由于在运行时对正则表达式求值的成本可能会很高,所以可以使用std::vector>,这样对于正则表达式模式,可以将编译后的正则表达式存储到其中一个字段中


为您想要完成的任务提供更多的背景信息可能会很有用,因为这可能有助于确定正确的数据结构和搜索算法。

使用两个地图怎么样

std::map<std::string, std::map<int, object> >
如果你想查找aaa/123,你可以

a.find("aaa")->find(123) 

(当然,您必须验证您没有结束,这只是一个示例)

我删除了我的答案,因为我想得不够:)我认为trie将是这个用例的理想选择。只需沿着trie的路径移动,直到找不到更多匹配项。看看这里:。如果前缀不仅是“aaa”,还可以是“aaa/bbb”,那该怎么办?如果你想要高效的东西,你需要制定一些明确的规则。你的最终目标是什么?是的,我认为这是一个很好的解决办法。如果地图中有许多元素,也可以依次调用find_prefix,搜索字符串的大小总是少一个。这将避免根据地图大小进行线性搜索,但现在取决于搜索字符串的大小。但我不知道这是否真的会更快。我有点不擅长这样的分析:)也许有些测试是正确的:)因为我的地图应该太大(最多几十个条目),而且密钥也或多或少受到相同数字的限制(字符串可以有多长?)-我想哪种方式最快并不重要。很好,那么我认为你的方式会很好。如果性能不会受到太大影响,那么就不必费心去尝试了。
a.find("aaa")->find(123)