J'ai un Vec
qui est l'allocation pour un tampon circulaire. Supposons que le tampon est plein, donc il n'y a aucun élément dans l'allocation qui ne soit pas dans le tampon circulaire. Je veux maintenant transformer ce tampon circulaire en Vec
où le premier élément du tampon circulaire est également le premier élément du Vec
. À titre d'exemple, je cette (allocation) fonction:Comment transformer un buffer circulaire en un vecteur dans O (n) sans allocation?
fn normalize(tail: usize, buf: Vec<usize>) -> Vec<usize> {
let n = buf.len();
buf[tail..n]
.iter()
.chain(buf[0..tail].iter())
.cloned()
.collect()
}
Il est évident que cela peut aussi être fait sans allouer quoi que ce soit, étant donné que nous avons déjà une allocation qui est assez grand, et nous avons une opération swap
échanger des éléments arbitraires de l'allocation.
fn normalize(tail: usize, mut buf: Vec<usize>) -> Vec<usize> {
for _ in 0..tail {
for i in 0..(buf.len() - 1) {
buf.swap(i, i + 1);
}
}
buf
}
Malheureusement, cela nécessite buf.len() * tail
opérations de swap. Je suis assez sûr qu'il peut être fait dans buf.len() + tail
opérations d'échange. Pour les valeurs concrètes de tail
et buf.len()
j'ai été en mesure de trouver des solutions, mais je ne suis pas sûr de savoir comment le faire dans le cas général.
Ma solution partielle récursive can be seen in action.
Ceci est souvent appelé "rotation" du vecteur, par ex. http://www.azillionmonkeys.com/qed/case8.html – huon
ah merveilleux. Mon google-fu m'a échoué. Je cherchais les mauvais termes. –
Je l'ai porté sur Rust [ici] (http://is.gd/geg4P6) si vous voulez ajouter une réponse avec du code. –