2016-04-12 20 views
1
için anahtar olarak HashSet

HashSet için HashSet<String> anahtarını bir anahtar olarak kullanmaya çalışıyorum. HashSet<String> için Hash özelliğini uygulamak için dikkat çeken this question and answer buldum, ancak özel durumumu çalıştıramıyordum.Diğer HashSet

Davam neyse ki daha ihtiyacım olanı öylesine bağlıdır geçerli: :

  • hash özelliği karma şimdilik çok basit olmalı HashSet<String>
  • türü için sadece Uygulamak

    Set {"q3", "q1", "q2"}, hash("q1-q2-q3") gibi basit, sıralı birleştirilmiş bir dize sürümü olarak hashed olmalıdır. "q1-q2-q3"'un elde edilmesi bir sorun değildir, ancak hash'un içinde kullanmayla baş edemediğim her türlü hataları atıyor.

    Bu benim uygulama denemem ancak işe yaramıyor. Ben tüm önemli HashSet yöntemleri

    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) kaybetmek çünkü StateSet sarıcı bunu yapmanın doğru yolu, olmadığını düşünüyorum, ana olanları varlık sizin koduyla bazı sorunlar vardı

cevap

3

Yeni tip sarmalayıcınızda onları arayarak HashSet yöntemlerine erişmeye çalışıyordunuz. numaralı telefondan, 'u self.0 ile değiştirerek doğrudan aramanız gerekir. İşte son çalışma kod: Ayrıca

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(); 
} 

, ben bunu sıralı bir şekilde elementler saklar olarak Hash uygulayan, hangi burada BTreeSet kullanmak tavsiye. Onun Hash uygulama kesinlikle tüm öğeleri bir O(n log(n)) sıralama yapan uygulamadan daha hızlı olmalıdır.

+1

Küçük nits: 'Vec <_>' ve 'a 'da' için. – Shepmaster

+0

Çok teşekkürler Dogbert! Cevabını doğru olanı olarak işaretleyeceğim. Kodunuzu kullanarak küçük bir çalışma örneği https://play.rust-lang.org/?gist=faad68f658e11f94ada25b6b0e8704f4&version=stable&backtrace=0 Kullanım durumuma uyup uymadığını görmek için BTreeSet hakkında daha fazla bilgi edeceğim çok! – franleplant

+1

Dogbert: BTreeSet'i test ettim ve aradığım şey _exactly_. Setin Im'iyle uğraştığım için kodumun bazı kısımlarında sipariş vermek gerekiyor, böylece doğal olarak uyuyorlar. Ayrıca, işleri daha da kolaylaştıracak olan Karma özelliğini uygulamanıza gerek yok. Çok teşekkürler! – franleplant