2016-11-07 38 views
2

这是一个概念性问题,所以我没有提供这个原因的“工作代码”。在C++中创建两个向量之间的链接

想象一个具有两个标准::不同类型和不同数量的实体的载体,只是举例:

vector <int> A; 
vector <string> B; 

一个具有一组规则以下中的哪一个可与某些A的任何成员相关联(或无)的成员B.

有没有办法“存储”此连接?

我在想的方式之一这么做是有一个vector <map <int, vector <string> > >vector <map <int, vector <string*> > >,但这种解决方案在我看来,不可靠的(如果A包含例如两个相同的数字),我以为有更优雅的解决方案,有没有什么地方。

+0

正如你所描述的,一个'std :: map >似乎更合适。 –

+0

@πάνταῥεῖ,这是一个实际需要的事情 - 快速检索a-> b或b-> a。因此,更复杂的解决方案将派上用场。 此外,没有什么能阻止我们在B中拥有相同的对象:) – greyxray

+0

提供更多信息 - 如果A(B)中有重复,他们将如何映射到B(A)?或者实际上是否意味着你将矢量位置/索引关联起来?这是一个关于函数(数学)然后是代码的更多问题。例如 – kabanus

回答

2

您可以实现一些数据库技术:指数。将您的数据放入一个单独的vector,然后创建std::map,您可以为每种要索引数据或关联数据的方式创建数据。

而不是2个载体,使结构的一个载体:

struct Datum 
{ 
    int value; 
    string text; 
}; 

// The database 
std::vector<Datum> database; 

// An index table by integer 
std::map<int, // Key 
     unsigned int vector_index> index_by_value; 

// An index table, by text 
std::map<std::string, // Key 
     unsigned int index_into_vector> index_by text; 

索引表给你一个快速的方法来在数据库中找到的东西,而不必进行排序数据库。

2

std::pairstd::multiset s就能够多int*点地图到零个或多个std::string* S:

std::multiset < std::pair<int*, std::vector<std::string*>>> map_A_to_B; 

实施例:

#include <set> 
#include <vector> 
#include <string> 
#include <utility> 
#include <iostream> 

int main() 
{ 
    std::vector<int> A{3,3,1,5}; 
    std::vector<std::string> B{"three a", "three b", "one", "five", "unknown"}; 
    std::multiset < std::pair<int*, std::vector<std::string*>>> map_A_to_B{ 
     {&A[0],{&B[0],&B[1]}}, 
     {&A[1],{&B[0],&B[1],&B[4]}}, 
     {&A[2],{&B[2]}}, 
     {&A[3],{&B[3]}}, 
    }; 

    for(auto e : map_A_to_B) { 
     for(auto s : e.second) { 
      std::cout << *e.first << " linked to " << *s << '\n'; 
     } 
     std::cout << "------------------------------\n"; 
    } 
} 

生产:

3 linked to three a 
3 linked to three b 
------------------------------ 
3 linked to three a 
3 linked to three b 
3 linked to unknown 
------------------------------ 
1 linked to one 
------------------------------ 
5 linked to five 
------------------------------ 
1

基于根据你的评论,这似乎就像你一样蚂蚁是实际的映射(如在数学中,从集合A到集合B),这是一般的(非一对一或上到)。首先你必须从概念上理解你想要的东西。首先,你想要一个类A(在你的例子中是int)到B(字符串)之间的映射。让我们模板此:

template <class From, class To> 
bool isMapped(From A,To B) { 
    return (//Code representing mapping,say check if A=int->char is in B=string) 
} 

现在From值转移到To向量的映射(在数学方面)范围内的“要”,这是到达(isMapped)形成这个值:

template<class From, class To> 
List<To>& getRange(From value, To range) { 
    List<To> result(); 
    for (const auto& toValue : range) { 
     if(isMapped(value,toValue) 
      result.push_back(toValue); 
    return result; 

这将返回From值在To向量中映射到的范围,如果它们在该范围内出现多次,则会有重复项。另一个选项(可能更好)是遍历索引而不是范围内的值,并在From映射到的索引中返回长度为rangetrue的布尔向量。

同样,你需要定义相反的映射。也许你无法做到这一点是完全一般的,甚至模板也不适合这一点 - 你需要提供更多细节。因此,从A到B的映射将是在相关索引中具有真/假的长度为B(域)的向量的向量A(域)的向量。

当然有更多的可能性。

1

你可以使用Boost来实现一个bidirectional map - 这将允许你使用任何一个值作为关键。 Here is an example of how to use it。但是,在短期:(只使用,不定义)

struct from {}; // tag for boost 

typedef bidirectional_map<int, std::string>::type bi_map; 

bi_map values; 
values.insert(bi_map::value_type(123, "{")); 

// ... 
// ... 

bi_map::iterator it = values.get<from>().find(123); 
if (it != values.end()) { 
    cout << "Char #123 is " << it->second << endl; 
    // and in the opposite case, where "it" is the result of: 
    // values.get<to>().find("{") 
    // it->second would be 123, so you have access to both items 
}