2017-08-10 113 views
1

我需要在自定義結構數組中找到最頻繁的元素。他們沒有自定義ID只是匹配屬性。C++ - 基於頻率排序自定義結構向量

我想按頻率排序我的載體,但我不知道該怎麼做。

+3

最簡單的就是使用'std :: sort'並提供一個lambda函數來比較你需要的東西。 – user0042

+0

您可以顯示一個結構將看起來像什麼,然後一個未排序的向量和您想要的排序向量的例子嗎? – CoryKramer

+3

它幾乎聽起來像你需要構建一個直方圖。如果是這種情況'std :: map'確實很好。 – NathanOliver

回答

2

我假設的頻率是指數組中出現相同結構的次數。

您可能需要爲自定義結構創建散列函數(或爲您的類型重載std::hash<>)。然後迭代你的數組,爲數組中的每個結構增加一個unordered_map<mytype, int>的值。這會給你在價值領域的頻率。像下面的東西會工作:

std::array<mytype> elements; 
std::unordered_map<mytype, int> freq; 
mytype most_frequent; 
int max_frequency = 0; 
for (const mytype &el : elements) { 
    freq[el]++; 
    if (freq[el] > max_frequency) { 
     most_frequent = el; 
    } 
} 

對於這項工作,該地圖將需要能夠創造一個哈希上述功能。默認情況下,它會嘗試使用std :: hash <>。標準明確允許您在標準名稱空間中爲您自己的類型專門化此模板。您可以這樣做:

struct mytype { 
    std::string name; 
    double value; 
}; 
namespace std { 
    template <> struct hash<mytype> { 
     size_t operator()(const mytype &t) const noexcept { 
      // Use standard library hash implementations of member variable types 
      return hash<string>()(t.name)^hash<double>()(t.value) 
     } 
    } 

} 

主要目標是確保任何兩個不包含完全相同值的變量將生成不同的哈希值。以上將各種類型的標準庫哈希函數的結果異或,其中according to Mark Nelson可能與單獨的哈希算法異或。由cppreference的hash reference建議的替代算法是Fowler-Noll-Vo hash function

+0

也許使用'for(const mytype&el:elements)'來避免創建每個元素的副本。 – StaticBeagle

+0

好點,固定。 – jhauris

+0

你可以使用'std :: map',而不用費力編寫散列函數,除非你有足夠的元素來保證恆定的訪問時間有很大的不同。 – Useless

1

看看std::sort和ref中提供的例子,在那裏你實際上通過你自己的比較器來做你想要的技巧(在你的情況下,使用頻率)。當然,如果你願意,也可以使用lambda函數。

+1

我不明白你是如何做到這一點的,因爲我認爲你需要一遍才知道每一遍元素頻率。如果你有一個想法,我有興趣看到它。 – jhauris

+0

您的答案可能不完整。我認爲OP要求根據向量中某些結構的發生頻率來排序向量。即 - 如果你有這些數字{6,4,7,6,1,4,9,6},並且你想按照每個數字出現的頻率對它們進行排序,你不能只是簡單的排序。 – RichS