【问题标题】:finding element in map with list c++使用列表c ++在地图中查找元素
【发布时间】:2014-07-27 11:54:29
【问题描述】:

我有一个带有整数(x)和列表(列表)的多图。

std::map<int,std::list<int> > my_map;

假设 mylist1 由元素 100,200,300 组成,我将其映射到整数 1

mylist2 由元素 99,199,299 组成,我将其映射到整数 2

my_map.insert(pair<int,std::list<int> > (1, mylist1));
my_map.insert(pair<int,std::list<int> > (2, mylist2));

现在给定一个元素说 200,我如何返回值 1(说元素 200 属于 映射到整数元素 1 的列表?

【问题讨论】:

  • 当你声明它为std::map&lt;&gt;时,它不是一个多图。这只是一张普通的地图。另外,在插入地图时查找make_pair()
  • 感谢修复它。还有关于如何搜索它的任何想法?

标签: c++ list map stl multimap


【解决方案1】:

您应该使用列表的元素作为键,使用整数作为值。 鉴于你的例子:

std::multimap<int, int> my_map;
my_map.insert(std::make_pair(100, 1));
my_map.insert(std::make_pair(200, 1));
my_map.insert(std::make_pair(300, 1));

my_map.insert(std::make_pair(99, 2));
my_map.insert(std::make_pair(199, 2));
my_map.insert(std::make_pair(299, 2));

那么就使用std::multimap&lt;int,int&gt;::equal_range函数

【讨论】:

  • 这个问题可能不是很有效,因此我选择使用列表。
  • @codebreaker 效率不高怎么办?你需要考虑什么对你的数据结构很重要。多图以什么方式效率不高?为什么以及如何列表对您更有效。在不了解问题的局限性的情况下,您无法获得如何有效地解决您的问题的好答案。
  • @codebreaker 我不同意你的看法。这种索引将是有效的,因为您的查询类型将具有与列表中不同元素的数量相关的对数复杂性。如果您只是进行蛮力搜索,则它是线性时间。对我来说,最好建立一次索引(花费线性时间用数据填充地图)然后进行有效的搜索。
【解决方案2】:

正如@NirMH 所说——迭代地图有什么问题? 我假设您使用的是 C++98 标准编译器。这是给你的简单代码(http://rextester.com/WVBE96570):

#include <iostream>
#include <map>
#include <list>
#include <algorithm>

int main()
{
    std::map<int, std::list<int> > my_map;
    std::list<int> l1;
    l1.push_back(10);
    l1.push_back(20);

    std::list<int> l2;
    l2.push_back(30);
    l2.push_back(40);

    my_map[1] = l1;
    my_map[2] = l2;

    int value_to_find = 40;
    int list_index = -1;
    for(std::map<int, std::list<int> >::const_iterator p_int_list_pair = my_map.begin(),
        end = my_map.end(); p_int_list_pair != end; ++p_int_list_pair)
    {
        const int& curr_index = p_int_list_pair->first;
        const std::list<int>& curr_list = p_int_list_pair->second;
        std::list<int>::const_iterator curr_list_end = curr_list.end();
        if(std::find(curr_list.begin(), curr_list_end, value_to_find) != curr_list_end)
        {
            list_index = curr_index;
            break;
        }
    }

    std::cout << list_index;
}

【讨论】:

  • 顺便说一句,在你的情况下使用 map 不是一个好主意。如果你想使用地图 - 按照@nikitoz 说的做
  • 你会推荐哪种其他数据结构?
  • 在你的情况下,我认为最好的办法是使用简单的向量对(std::vector<:pair>, int >>)。这将是简单而好的。
【解决方案3】:

伪代码:

Iterate over my_map
   For every iteration, search the value (list<int>) for your target integer
   If found, return the my_map iterator first item

您可以使用algorithm 标头中的find 方法来优化搜索。

【讨论】:

  • 有这样的例子吗?
  • @codebreaker - 具体是什么例子?让我知道你在寻找什么
【解决方案4】:

这是我的 C++11 版本:

#include <algorithm>
#include <iostream>
#include <list>
#include <map>
#include <utility>

using value_type = int;
using list_type = ::std::list<value_type>;
using key_type = int;
using map_type = ::std::map<key_type, list_type>;
using pair_type = map_type::value_type;


list_type my_list_1;
list_type my_list_2;
map_type my_map;


map_type::const_iterator find_key_of_first_list_containing (const value_type x, const map_type & map)
{
    auto map_cend = map.cend();
    for (auto map_cit = map.cbegin(); map_cit != map_cend; ++map_cit)
    {
        auto list = map_cit->second;
        auto list_cend = list.cend();
        auto list_cit = ::std::find(list.cbegin(), list_cend, x);
        if (list_cit != list_cend)
            return map_cit;
    }
    return map_cend;
}


int main (int, char **)
{
    my_list_1.push_back(100);
    my_list_1.push_back(200);
    my_list_1.push_back(300);

    my_list_2.push_back(99);
    my_list_2.push_back(199);
    my_list_2.push_back(299);

    my_map.insert(pair_type(1, my_list_1));
    my_map.insert(pair_type(2, my_list_2));

    auto i = find_key_of_first_list_containing(200, my_map);

    if (i != my_map.end())
        ::std::cout << "Found at: " << i->first << "\n";
    else
        ::std::cout << "Not found!\n";

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2011-01-12
    • 2016-07-18
    • 2011-03-03
    • 2015-02-07
    • 1970-01-01
    相关资源
    最近更新 更多