Смещение элементов массива по заданным индексам

#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], а не заменой на обратный?