0

What is the most efficient algorithm to shift array elements at specified indices left and right by one position?

For example shift indices [1,3,5] of [a,b,c,d,e,f] to the left to get [b,a,d,c,f,e]

I don't want it to rotate if the new index is out of bounds, if that makes sense.

I am using C++ std::vector for array storage.

5
  • Do you mean to swap places with the previous entry? Commented Jul 2, 2014 at 19:24
  • have you thought just using std::swap? Commented Jul 2, 2014 at 19:24
  • Your indices are off by one. Commented Jul 2, 2014 at 19:32
  • oops, fixed, thank you. Commented Jul 2, 2014 at 19:37
  • @toastie Do you want to swap all elements taken 2 at a time, or only specific indices with the elements to their left? Commented Jul 2, 2014 at 19:39

2 Answers 2

2

I'm interpreting your question as to swap the two adjacent entries of an array based on index. If this is wrong, then please clarify your question with an example for which this is not correct.

void swapElements(const std::vector<int>& indexes, std::vector<int>& array){
    for(auto i : indexes){
        if (i < 1 || i >= array.size()){
            continue;
        }
        std::swap(array[i-1], array[i]):
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Can you please fix your const usage?
And: i >= array.size()
Oops. I really should pay more attention.
Yep, that's it, thank you! I can figure out doing it the other direction from here.
One caveat here is that it seems indexes need to be sorted for this to work correctly.
|
0

I think the simplest way is to use std::swap with the element with the given index and the element that preceds it.

For the first element you can use

std::swap( v.front(), v.back() );

Here is an example

#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;
}

The output is

a b c d e f 
b a d c f e 

If you do not want to rotate the vector then you can sibstitute the if statement for the following

for ( size_t i : { 1, 3, 5 } )
{
    if ( 0 < i && i < v.size() ) std::swap( v[i], v[i-1] );
}

1 Comment

He said he didn't want to swap if the previous would be out of range, so wouldn't it be a no-op for [0], not a swap with the back?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.