地图复杂查找操作

时间:2009-02-17 13:43:12

标签: 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.

知道我是如何用C ++和可能的STL / boost做到的吗?

3 个答案:

答案 0 :(得分:3)

这是一个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
}

我忘了添加使用它的代码:

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()

任何评论(感谢litb)?

答案 1 :(得分:1)

根据您的要求,您似乎并不真正想要地图数据结构,但可以设置或非常简单。

我认为像这个std :: map这样的结构可能对你有帮助。 Boost :: any将能够存储任何东西,但需要注意的是你需要知道值类型是要读回来的。

Key是字符串,因此它也可以是正则表达式。使用此结构,您将需要两个传递算法:

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 :: vector&gt;,这样对于正则表达式模式,您可以将已编译的正则表达式存储到其中一个字段中。

为您提供更多背景知识可能会有所帮助,因为它可能有助于确定正确的数据结构和搜索算法。

答案 2 :(得分:0)

使用两张地图怎么样?

std::map<std::string, std::map<int, object> >

如果你想查找aaa / *,你可以

a.find("aaa") => you get an iterator to the map with all "aaa" prefix

如果你想查找aaa / 123,你可以

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

(当然你必须确认你没有结束,这仅仅是为了这个例子)