2016-08-08 4 views
4

Bietet die Standardbibliothek die Möglichkeit, ein Segment [T] mit einem anderen Segment desselben Typs als Trennzeichen zu teilen? Die Dokumentation der Bibliothek listet Methoden auf, die mit Ein-Element-Trennzeichen statt mit Slices arbeiten.Wie können Slices mit einem anderen Slice als Trennzeichen geteilt werden?

Zum Beispiel: Eine Scheibe von 5 u64 ganzen Zahlen [1u64, 4u64, 0u64, 0u64, 8u64][0u64, 0u64] aufgeteilt, wobei als Trennzeichen in zwei Scheiben [1u64, 4u64] und [8u64] führen würde.

Antwort

3

Bietet die Standardbibliothek die Möglichkeit, ein Segment [T] mit einem anderen Segment desselben Typs als Trennzeichen zu teilen?

Ab Rust 1.9, nein, aber man kann es implementieren:

fn main() { 
    let a = [1, 4, 7, 0, 0, 8, 10, 0, 0]; 
    let b = [0, 0]; 
    let mut iter = split_subsequence(&a, &b); 
    assert_eq!(&[1, 4, 7], iter.next().unwrap()); 
    assert_eq!(&[8, 10], iter.next().unwrap()); 
    assert!(iter.next().unwrap().is_empty()); 
    assert_eq!(None, iter.next()); 
} 

pub struct SplitSubsequence<'a, 'b, T: 'a + 'b> { 
    slice: &'a [T], 
    needle: &'b [T], 
    ended: bool, 
} 

impl<'a, 'b, T: 'a + 'b + PartialEq> Iterator for SplitSubsequence<'a, 'b, T> { 
    type Item = &'a [T]; 

    fn next(&mut self) -> Option<Self::Item> { 
     if self.ended { 
      None 
     } else if self.slice.is_empty() { 
      self.ended = true; 
      Some(self.slice) 
     } else if let Some(p) = self.slice 
            .windows(self.needle.len()) 
            .position(|w| w == self.needle) { 
      let item = &self.slice[..p]; 
      self.slice = &self.slice[p + self.needle.len()..]; 
      Some(item) 
     } else { 
      let item = self.slice; 
      self.slice = &self.slice[self.slice.len() - 1..]; 
      Some(item) 
     } 
    } 
} 

fn split_subsequence<'a, 'b, T>(slice: &'a [T], needle: &'b [T]) -> SplitSubsequence<'a, 'b, T> 
    where T: 'a + 'b + PartialEq 
{ 
    SplitSubsequence { 
     slice: slice, 
     needle: needle, 
     ended: false, 
    } 
} 

Beachten Sie, dass diese Implementierung eine gleiche Teilfolge zum Auffinden eines naive-Algorithmus verwendet.

+0

Der naive Algorithmus ist O (n^2), ich glaube, das ist ein Grund, warum es nicht in der Standardbibliothek enthalten ist. – Shepmaster

+0

Das habe ich getan. +1 für die Zeit, um Ihre Antwort mit einer Implementierung zu veranschaulichen. – Doe

Verwandte Themen