在c ++中创建两个向量之间的链接

时间:2016-11-07 19:47:10

标签: c++ design-patterns vector

这是一个概念性问题,因此我没有提供“工作代码”。

想象一下有两个不同类型和不同数量的实体的std :: vector,例如:

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

一个人有一套规则,之后可以将A的任何成员与B的一些(或没有)成员联系起来。

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

我认为其中一种方法是使用vector <map <int, vector <string> > >vector <map <int, vector <string*> > >,但这种解决方案对我来说似乎不可靠(如果A包含两个相同的数字),我假设在那里的某处是更优雅的解决方案。

4 个答案:

答案 0 :(得分:2)

require std::multisetstd::pair可以将多个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 :(得分: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 :(得分: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向量的映射(以数学术语表示)&#34; To&#34;可达的(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(域)长度的向量,相关索引中为True / False。

当然,还有更多的可能性。

答案 3 :(得分:1)

您可以使用Boost实现bidirectional map - 这将允许您使用任一值作为键。 Here is an example of how to use it。但是,简而言之:(仅限使用,没有定义)

with open('thefile.txt') as infile:
    while True:
        parts = [infile.readline() for _ in range(4)]
        if not any(parts):
            break
        part1, part2, part3, part4 = parts