#c #arrays #sorting #stdvector #indices
#c #массивы #сортировка #stdvector #индексы
Вопрос:
Какой наиболее эффективный алгоритм сдвигает элементы массива по заданным индексам влево и вправо на одну позицию?
Например, сдвиньте индексы [1,3,5] из [a, b, c, d, e, f] влево, чтобы получить [b, a, d, c, f,e]
Я не хочу, чтобы он вращался, если новый индекс выходит за рамки, если это имеет смысл.
Я использую C std::vector для хранения массива.
Комментарии:
1. Вы имеете в виду поменять местами предыдущую запись?
2. вы думали просто использовать
std::swap
?3. Ваши индексы отклонены на единицу.
4. упс, исправлено, спасибо.
5. @toastie Вы хотите поменять местами все элементы, взятые по 2 за раз, или только определенные индексы с элементами слева от них?
Ответ №1:
Я интерпретирую ваш вопрос как поменять местами две смежные записи массива на основе индекса. Если это неверно, то, пожалуйста, поясните свой вопрос примером, для которого это неверно.
void swapElements(const std::vector<int>amp; indexes, std::vector<int>amp; array){
for(auto i : indexes){
if (i < 1 || i >= array.size()){
continue;
}
std::swap(array[i-1], array[i]):
}
}
Комментарии:
1. Не могли бы вы, пожалуйста, исправить свое постоянное использование?
2. И: i >= array.size()
3. Упс. Мне действительно следует уделять больше внимания.
4. Да, вот и все, спасибо вам! Я могу придумать, как сделать это в другом направлении отсюда.
5. Одно предостережение здесь заключается в том, что, по-видимому, индексы должны быть отсортированы, чтобы это работало правильно.
Ответ №2:
Я думаю, что самый простой способ — использовать std::swap
с элементом с заданным индексом и элементом, который предшествует ему.
Для первого элемента вы можете использовать
std::swap( v.front(), v.back() );
Вот пример
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<char> v = { 'a', 'b', 'c', 'd', 'e', 'f' };
for ( char c : v ) std::cout << c << ' ';
std::cout << std::endl;
for ( size_t i : { 1, 3, 5 } )
{
if ( i == 0 ) std::swap( v.front(), v.back() );
else if ( i < v.size() ) std::swap( v[i], v[i-1] );
}
for ( char c : v ) std::cout << c << ' ';
std::cout << std::endl;
return 0;
}
Результат таков
a b c d e f
b a d c f e
Если вы не хотите поворачивать вектор, вы можете использовать оператор if для следующего
for ( size_t i : { 1, 3, 5 } )
{
if ( 0 < i amp;amp; i < v.size() ) std::swap( v[i], v[i-1] );
}
Комментарии:
1. Он сказал, что не хочет менять местами, если предыдущий будет вне диапазона, так разве это не было бы отказом для [0], а не заменой на обратный?