2016-11-07 63 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 
} 
相關問題