1) в Rust?
let mut some_vec = vec![String::from("aaa"), String::from("bbb"), String::from("ccc"), String::from("")];
После перемещения some_vec должен выглядеть так: { "aaa", "aaa", "bbb", "ccc" }
Первый элемент после изменения может быть любым* (необязательно aaa)
А куда пустая строка делать?...
Пустая строка не играет роли, её можно убрать
а её важно убрать?
Пока выглядит как let first = vec[0].clone(); vec.insert(1, first); Но только учти, что это O(n)
Вообще всё равно на эту строку. Мне лишь важно сделать std::move(vec.begin(), vec.end() - 1, vec.begin() + 1) (который работает ведь за O(1)?) То есть хотелось бы "сдвигать" часть вектора за константу. Было: {a, b, c, d}, стало {a, a, b, c} (и даже не важно каким будет vec[0] после трансформации)
сдвигать часть вектора за константу не возможно, тебе надо все элементы скопировать
так нельзя, это не линкед лист
template<class InputIt, class OutputIt> OutputIt move(InputIt first, InputIt last, OutputIt d_first) { while (first != last) { *d_first++ = std::move(*first++); } return d_first; }
Спасибо! Немного был озадачен тем, что есть ещё и [std::move](https://en.cppreference.com/w/cpp/utility/move) из <utility>
template? Это что-то на сишном
Ну так std::move откуда?
Я тут ещё и UB создал 🙃 > (контекст: OutputIt move( InputIt first, InputIt last, OutputIt d_first ); The behavior is undefined if d_first is within the range [first, last)
Понял, что у Vec есть swap (и даже rotate_*!) Так что можно сделать так (если честно, немного грустно, что Vec::swap сделан через вызов unsafe метода, который вызывает ptr::swap, который в свою очередь вызывает copy и copy_nonoverlapping, которые в свою очередь являются интринсиками)
Но зачем? Почему не сделать просто if let Some(last) = vec.pop() { vec.insert(0, last); } это будет тоже самое, если не лучше по ""производительности"" и уж точно легче читается
Не понял в чём грусть впрочем
да и вообще, реально, почему просто не сделать rotate_right(1)? Ещё легче читается, не вижу вообще проблем...
Честно, не знаю как. Вообще думал, что такие операции получится сделать без unsafe, но по итогу внутри есть unsafe. Хотя это и справедливо, ведь манипулировать сырыми указателями — это опасно, здесь надо быть внимательным.
Ну стдлиб раста даёт слой над ансейфовым миром, а не магическим образом делает всё сейфовым)
rotate_right - к деку, а не вектору тогда уж
Safe подмножество строится исключительно на ансейфе с проверенными обёртками
Не понял вас. дек — VecDeque? У него есть rotate_right У Vec тоже есть rotate_right
rotate_right у VecDeque — O(n), где n — параметр (rotate_right(n)) rotate_right у Vec — O(n), где n — размер вектора (vec.len())
а, ну вот в документации написано: Vec — Takes linear (in self.len()) time. VecDeque — Takes O(min(k, len() - k)) time and no extra space.
Отличный вариант, имхо, что еще вам нужно?
rotate_right чем хуже?
Что ты по итогу сделал, если не секрет?
Vec. Вообще при маленьких значениях без разницы ведь, что брать, но с Vec я уже знаком!
Я про повороты, сдвиги, шаманство с материнской платой. Что решил использовать?
rotate_right. Можно, конечно, изобрести велосипед, но зачем?
вообще я решал задачу на LeetCode (Burst Balloons). Там дан Vec<i32> и чтобы не мучиться с границами, я решил "по бокам" добавить единицы. было: [a, b, c, d], стало: [1, a, b, c, d, 1] ну и можно было бы сделать это двумя разными способами: 1)vec.push(1); vec.insert(0); 2) vec.resize(vec.len() + 2, 1); vec.rotate_right(1); первый способ проще понять и проще написать
есть ещё третий путь (я бы так в первую очередь попыталась сделать): use std::iter::once; let vec = once(1).chain(vec.into_iter()).chain(once(1));
Обсуждают сегодня