2016-04-12 7 views
1

HashSet<String>を他のキーのキーとして使用しようとしています。HashSetのキーとして使用しています。 HashSet<String>Hash特性を実装すると指摘しているthis question and answerが見つかりましたが、私の場合は動作させることができませんでした。他のHashSetのキーとしてのHashSet

私の場合は、幸いにも多くの私が必要なものをとてもバインドされている: :

  • hash特性ハッシュは今のところ非常にシンプルであるべきHashSet<String>
  • タイプのためにのみを実装

    セット{"q3", "q1", "q2"}は、単純な順序付けされた連結文字列バージョン(例えば、hash("q1-q2-q3"))としてハッシュされる必要があります。取得する"q1-q2-q3"は問題ではありませんが、hashの中でそれを使用すると、私は対処できないすべての種類のエラーをスローします。

    これは私の実装の試みですが、動作しません。私は私がすべての重要なHashSet方法

    use std::collections::{HashMap,HashSet}; 
    use std::hash::{Hash,Hasher}; 
    
    type State = String; 
    struct StateSet(HashSet<State>); 
    
    impl PartialEq for StateSet { 
        fn eq(&self, other: &StateSet) -> bool { 
         self.is_subset(&other) && other.is_subset(&self) 
        } 
    } 
    
    impl Eq for StateSet {} 
    
    impl Hash for StateSet { 
        fn hash<H>(&self, state: &mut H) where H: Hasher { 
         let a: Vec<State> = self.iter().collect(); 
         a.sort(); 
         for s in a.iter() { 
          s.hash(state); 
         } 
        } 
    
    } 
    
    fn main() { 
        let hmap: HashSet<StateSet> = HashSet::new(); 
    } 
    

    playground)を失うのでStateSetラッパーがそれを行うための正しい方法は、ないと思われる、主なものは、ということで、あなたのコードにはいくつかの問題がありました

答えて

3

あなたはあなたのnewtypeラッパーでそれらを呼び出すことによってHashSetのメソッドにアクセスしようとしていました。 selfself.0に置き換えて直接HashSetに電話する必要があります。ここでは、最終的な作業のコードがあります:

use std::collections::{HashMap,HashSet}; 
use std::hash::{Hash,Hasher}; 

type State = String; 
struct StateSet(HashSet<State>); 

impl PartialEq for StateSet { 
    fn eq(&self, other: &StateSet) -> bool { 
     self.0.is_subset(&other.0) && other.0.is_subset(&self.0) 
    } 
} 

impl Eq for StateSet {} 

impl Hash for StateSet { 
    fn hash<H>(&self, state: &mut H) where H: Hasher { 
     let mut a: Vec<&State> = self.0.iter().collect(); 
     a.sort(); 
     for s in a.iter() { 
      s.hash(state); 
     } 
    } 

} 

fn main() { 
    let hmap: HashSet<StateSet> = HashSet::new(); 
} 

また、私は非常にそれがソート順に要素を格納してHash実装され、ここでBTreeSetを使用するためにあなたをお勧めします。そのHash実装は間違いなくすべての項目のO(n log(n))並べ替えを行う実装よりも速くする必要があります。

+1

マイナーニッツ: 'Vec <_>'と 'for s a a'。 – Shepmaster

+0

ありがとうDogbert!あなたの答えを正しいものとしてマークします。 あなたのコードを使用した少し実用的な例を以下に示します。https://play.rust-lang.org/?gist=faad68f658e11f94ada25b6b0e8704f4&version=stable&backtrace=0 私は使用例に合っているかどうかを確認するためにBTreeSetについて詳しく説明します。ロット! – franleplant

+1

Dogbert:私はBTreeSetをテストしましたが、それらは私が探していたものと全く同じです。セットの私の扱っているので、私のコードのいくつかの部分で注文する必要がありますので、彼らは自然に適合します。また、ハッシュの特性を実装する必要はありません。どうもありがとう! – franleplant