Как найти и заменить каждый соответствующий фрагмент байта другим фрагментом? - PullRequest
0 голосов
/ 11 января 2019

У меня есть байтовый вектор, и я хочу заменить каждый [1, 2, 3] на [4, 5, 6]. Как это возможно в Rust?

let mut buf = vec![1, 2, 3, 7, 8];

// ?

assert_eq!(buf, vec![4, 5, 6, 7, 8]);

Ответы [ 3 ]

0 голосов
/ 11 января 2019

без рекурсии:

fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T])
where
    T: Clone + PartialEq,
{
    for i in 0..=buf.len() - from.len() {
        if buf[i..].starts_with(from) {
            buf[i..(i + from.len())].clone_from_slice(to);
        }
    }
}
0 голосов
/ 03 мая 2019

Это работает, когда ломтики имеют разную длину (аналогично replace для str):

fn replace<T>(source: &[T], from: &[T], to: &[T]) -> Vec<T>
where
    T: Clone + PartialEq
{
    let mut result = source.to_vec();
    let from_len = from.len();
    let to_len = to.len();

    let mut i = 0;
    while i + from_len <= result.len() {
        if result[i..].starts_with(from) {
            result.splice(i..i + from_len, to.iter().cloned());
            i += to_len;
        } else {
            i += 1;
        }
    }

    result
}
0 голосов
/ 11 января 2019

Эта функция может выполнять работу:

fn replace_slice<T>(source: &mut [T], from: &[T], to: &[T])
where
    T: Clone + PartialEq,
{
    let iteration = if source.starts_with(from) {
        source[..from.len()].clone_from_slice(to);
        from.len()
    } else {
        1
    };

    if source.len() > from.len() {
        replace_slice(&mut source[iteration..], from, to);
    }
}

Эта функция рекурсивная, но вы также можете переписать ее, используя циклы.


Пример 1:

fn main() {
    let mut buf = vec![1, 2, 3, 7, 8, 1, 2, 3];

    replace_slice(&mut buf[..], &[1, 2, 3], &[4, 5, 6]);

    assert_eq!(buf, vec![4, 5, 6, 7, 8, 4, 5, 6]);
}

Детская площадка


Пример 2: (Из комментария trentcl)

fn main() {
    let mut buf = vec![1, 2, 3, 3, 4, 1, 2, 3];

    replace_slice(&mut buf[..], &[1, 2, 3], &[5, 1, 2]);

    assert_eq!(buf, vec![5, 1, 2, 3, 4, 5, 1, 2]);
}

Детская площадка

...