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

Creating a link between two vectors in c++

本文关键字:向量 两个 之间 链接 c++ 创建      更新时间:2023-10-16

这是一个概念性问题,因此我不提供"工作代码"。

假设有两个不同类型和不同数量实体的std::vector,例如:

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

一个人有一组规则,根据这些规则可以将a的任何成员与b的一些(或没有)成员关联起来

是否有一种方法来"存储"这个连接?

我认为这样做的方法之一是拥有vector <map <int, vector <string> > >vector <map <int, vector <string*> > >,但这种解决方案对我来说似乎不可靠(例如,如果a包含两个相同的数字),我认为在那里有更优雅的解决方案。

您可以实现一些数据库技术:索引。将您的数据放入单个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;

索引表为您提供了在数据库中查找内容的快速方法,而不必对数据库进行排序。

std::pair s的std::multiset将能够将多个int* s映射到零个或多个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
------------------------------

根据你的评论,似乎你想要一个实际的映射(如在数学中,从集合a到集合B),这是一般的(不是一对一或上)。首先,你必须从概念上理解你想要什么。首先,需要在类a(在示例中为int)到类B (string)之间建立映射。让我们把它作为模板:

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向量的映射(用数学术语来说)是"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向量中映射到的范围,如果它们在该范围中出现多次,则返回重复的范围。另一种选择(可能更好)是迭代索引而不是范围内的值,并返回一个长度为range的布尔向量,其中true在From映射到的索引中。

类似地,您需要定义相反的映射。也许你不能让这个完全通用,也许甚至模板都不适合这个简单-你需要给出更多的细节。

由此得出,A到B的映射是长度为A的向量(定义域)的长度为B的向量(定义域)的向量,其相关指标为True/False。

当然还有更多的可能性

您可以使用Boost实现双向映射—这将允许您使用任何一个值作为键。下面是如何使用它的一个例子。但是,简而言之:(仅限用法,没有定义)

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
}