2017-08-17 1 views
0

Ich habe einen Vektor:Wie erhält man den Wert der nächsten Iteration in der aktuellen Iteration in Rust for loop?

let mut v: Vec<Vec<i32>> = Vec::new(); 
// [[1, 2, 3], [7, 8, 9], [3, 4, 5], [12, 13, 14], [5, 6, 7]]` 

Ich versuche, es zu sortieren:

// [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [12, 13, 14]] 

Ich habe dieses Vektor von Vektoren durch die ‚Fortsetzung‘ jedes letzte Element neu zu organisieren. Wichtig ist, dass ich die Position von Elementen in Vektoren nicht ändern kann. Ich kann die Positionen nur ganzer Vektoren ändern.

Wie kann ich den Wert der nächsten Iteration in der aktuellen Iteration abrufen?

for n in v { 
    temp_current_first = n[0]; // OK 
    temp_current_last = n[n.len()-1]; // OK 
    temp_next_first = n+1[0]; // It's wrong, but something like this 
    temp_next_first = n.next()[0] // or this way ?? 
} 

Antwort

1
temp_next_first = n+1[0]; // It's wrong, but something like this 
temp_next_first = n.next()[0] // or this way ?? 

denen 2 funktionieren nicht, weil n eine einfache i32 ist, was bedeutet, dass es nicht, dass es Teil v weiß ist.


Falls Sie benötigen nur eine Iteration nach vorne schauen (am nächsten Punkt) Sie eine peekable iterator verwenden könnte, sondern weil Sie durch den gesamten vec scannen, das ist nicht das, was Sie hier benötigen .


Soweit ich verstehe Ihre Frage wollen Sie eine Art Kette haben, wo man das Ende eines Stücks gleich der Beginn des nächsten ist.

[4,3][3,7][7,5][5,9] // something like this. 

Ich denke, dass es wirklich tatsächlich kompliziert ist diese schnelle Art und Weise in einer eher zu tun. Eine Möglichkeit, dies zu tun, ist die folgende.

fn order<T: PartialEq>(vec: &mut Vec<(T,T)>) { 
    if vec.len() == 0 { 
     return; 
    } 

    let mut temp = vec![vec.remove(0)]; 

    'outer: loop { 
     let mut next: Option<usize> = None; 
     'inner: for (i, item) in vec.iter().enumerate() { 
      if item.0 == temp.last().unwrap().1 { 
       next = Some(i); 
       break 'inner; 
      } 
     } 

     match next { 
      Some(pos) => temp.push(vec.remove(pos)), 
      None => break 'outer, 
     } 
    } 
    *vec = temp; 
} 

Nun könnte man diese Funktion wie folgt aufrufen:

fn main() { 
    let mut v: Vec<(i32,i32)> = vec![(4,5),(2,8),(5,7)]; 

    order(&mut v); 

    println!("{:?}",v); 
} 

Dies sollte drucken: [(4, 5), (5, 7)]


ist mehr an der order Funktion in viel Detail aussehen lassen:

if vec.is_empty() { 
    return; 
} 

Zuerst sehen wir, ob vec leer ist, in diesem Fall verlassen wir einfach die Funktion.

let mut temp = vec![vec.remove(0)]; 

Wir schaffen eine neue Vec<i32,i32>, die das erste Element des alten VEC enthält, die wir entfernen.

'outer: loop { 
    let mut next: Option<usize> = None; 

    /* snip */   

    match next { 
     Some(pos) => temp.push(vec.remove(pos)), 
     None => break 'outer, 
    } 
} 
*vec = temp; 

Nun erstellen wir ein Option<usize>next genannt, wenn diese Null am Ende der 'outer Schleife ist, gab es kein passendes Element innerhalb von vec was bedeutet, dass wir diese Funktion zu beenden und stellen Sie den Vec wir als Eingabe bekam temp.

Wenn nextSome(value) ist, bedeutet es, dass wir ein passendes Paar von innen vec gefunden, die wir dann entfernen und in pushtemp. Danach starten wir einfach die Schleife von Anfang an.

'inner: for (i, item) in vec.iter().enumerate() { 
    if item.0 == temp.last().unwrap().1 { 
     next = Some(i); 
     break 'inner; 
    } 
} 

Hier haben wir iterate durch vec und vergleichen item.0 zur letzten element oder temp, falls diese beiden sind die gleichen wir müssen irgendwie diese element aus vec entfernen und in temp setzen. Leider können wir vec innerhalb von for nicht mutieren, weil die for -loop einen Verweis auf vec hat, was bedeutet, dass wir vec darin nicht ändern können.

Um dies zu umgehen rufen wir einfach enumerate() auf unserer vec.iter() dies sagt uns die Position der item wir entfernen möchten. Wenn nun if item.0 == temp.last().unwrap().1true ist, setzen wir next auf Some(i) (i ist die Position item) und verlassen die 'inner Schleife.

Dies sollte die Funktion in viel mehr Details erklären, als es wahrscheinlich sollte, hoffe, es hilft irgendwie.

3

Nun, wäre die einfachste Lösung nur tun sein:

v.sort(); 

, die nur die äußere Vektor sortieren wird. Andernfalls, wenn Sie es selbst implementieren möchten, würde ich empfehlen, verschiedene sorting algorithms zu betrachten, da es viele Möglichkeiten gibt, es zu tun.

+0

Dank @ljedrz Ich weiß nicht, dass diese einfache Funktion auf diese Weise sortieren. Aber was, wenn ich den Wert der nächsten Iteration in der aktuellen Iteration überprüfen möchte? – twistezo

+1

@twistezo 'sort()' verwendet die Eigenschaft 'Ord', um die Elemente einer Scheibe zu sortieren. 'Ord' ist auch für Arrays implementiert und vergleicht lexikografisch. –

Verwandte Themen