2010-05-05 74 views
4

示例代碼:<hash_set>平等的運營商並不在VS2010

std::hash_set<int> hs1; // also i try std::unordered_set<int> - same effect 
std::hash_set<int> hs2; 

hs1.insert(15); 
hs1.insert(20); 

hs2.insert(20); 
hs2.insert(15); 

assert(hs1 == hs2); 

的hash_set不專賣店元素通過哈希函數定義一些命令......爲什麼? 請注意,此代碼使用stdext :: hash_set在VS2008中工作。

+1

你是說,你希望'HS1 == hs2'是真實的,或者他們*是平等的,你不明白爲什麼? – jalf 2010-05-05 12:23:14

+0

我不明白他們爲什麼不相等=) 這個斷言失敗了,這是一個問題 – ProgramWriter 2010-05-05 13:16:39

回答

4

看起來平等的比較打破了在Visual C兩hash_setunordered_set ++ 2010

我實現了使用的語言,從標準quoted by Matthieu以驗證它是否是一個錯誤(只是無序的容器天真平等功能可以肯定的):

template <typename UnorderedContainer> 
bool are_equal(const UnorderedContainer& c1, const UnorderedContainer& c2) 
{ 
    typedef typename UnorderedContainer::value_type Element; 
    typedef typename UnorderedContainer::const_iterator Iterator; 
    typedef std::pair<Iterator, Iterator> IteratorPair; 

    if (c1.size() != c2.size()) 
     return false; 

    for (Iterator it(c1.begin()); it != c1.end(); ++it) 
    { 
     IteratorPair er1(c1.equal_range(*it)); 
     IteratorPair er2(c2.equal_range(*it)); 

     if (std::distance(er1.first, er1.second) != 
      std::distance(er2.first, er2.second)) 
      return false; 

     // A totally naive implementation of is_permutation: 
     std::vector<Element> v1(er1.first, er1.second); 
     std::vector<Element> v2(er2.first, er2.second); 

     std::sort(v1.begin(), v1.end()); 
     std::sort(v2.begin(), v2.end()); 

     if (!std::equal(v1.begin(), v1.end(), v2.begin())) 
      return false; 
    } 

    return true; 
} 

它返回hs1hs2從你的例子是相等的。 (有人讓你發現在代碼中的bug我知道,我真的沒有測試它廣泛...)

我會提交有關Microsoft連接的缺陷報告。

+0

缺陷報告鏈接:https://連接。microsoft.com/VisualStudio/feedback/details/557117/std-unordered-set-equality-comparison-broken-in-visual-c-2010 – 2010-05-05 15:12:41

+0

謝謝詹姆斯:)我不確定你的比較是最佳的,但我還沒有看到任何明顯的錯誤。無論如何,即使沒有我從標準中收集的代碼,「unordered_set」的相等性等同於「set」的相等性,不應該依賴於插入順序或刪除的可能性。 – 2010-05-06 06:10:19

2

終於找到最終草案中提及在23.2.5注11:

兩個無序容器ab比較相等,如果a.size() == b.size(),並從a.equal_range(Ea1)獲得每等效鍵組[Ea1,Ea2),有存在從b.equal_range(Ea1)獲得的等效密鑰組[Eb1,Eb2),使得distance(Ea1, Ea2) == distance(Eb1, Eb2)is_permutation(Ea1, Ea2, Eb1)返回true

我敢打賭hash_set現在在unordered_set(以開始)項實現,但我還是不明白,爲什麼在你的情況下,它會失敗。

複雜性要求在平均情況下爲O(N),但由於線性鏈實現要求,最壞情況下退化爲O(N )。

+0

作爲一個解決方案,我發現boost :: unordered_set ..但我再次感到失望在比利和他的團隊 – ProgramWriter 2010-05-05 12:37:47

1

我問這個問題here但沒有給出迴應=) 感謝您的反饋意見。

我也創造了一些簡單的控制檯測試(只是要確定):

#include <iostream> 
#include <hash_set> 
int main(int argc, char* argv[]) 
{ 
    stdext::hash_set<int> hs1, hs2; 
    hs1.insert(10); 
    hs1.insert(15); 
    hs2.insert(15); 
    hs2.insert(10); 
    std::cout << ((hs1 == hs2) ? "It works!" : "It NOT works") << std::endl; 
    return EXIT_SUCCESS; 
} 

和編譯。 使用VS2008命令提示符:

cl.exe HashSetTest.cpp /oHashSetTest2008.exe 

使用VS2010命令提示符:

cl.exe HashSetTest.cpp /oHashSetTest2010.exe 

我真的看到不同的結果=)