Циклический сдвиг элементов массива влево/вправо на k позиций
Дан массив размера N и число k (0<k<5,k<N).
Осуществить циклический сдвиг элементов массива влево/вправо на k позиций.
Ответы (1 шт):
Ладно, тот случай, когда вопрос хоть и учебный, но поучительный в смысле алгоритма. Поэтому отвечу.
Общий алгоритм циклического сдвига легко реализуется с помощью обращения порядка элементов. Рассмотрим, например, массив
a b c d e f g h i j k l
который надо сдвинуть на 4 позиции вправо. Это значит, что слева должны оказаться элементы i j k l. При обращении порядка элементов они именно там и окажутся, правда, в обратном порядке:
l k j i h g f e d c b a
Но если теперь развернуть только первые 4 элемента, они оказываются на своем месте...
i j k l h g f e d c b a
Осталось развернуть вторую часть - остальные 8 элементов:
i j k l a b c d e f g h
Вот и все, мы получили, что нужно.
Реализовать это легко с использование алгоритма reverse стандартной библиотеки, с использованием итераторов - начала последовательности, средины (куда сдвигать первый элемент) и конца:
template<typename BidirIt>
void rot(BidirIt first, BidirIt mid, BidirIt last)
{
reverse(first,last);
reverse(first,mid);
reverse(mid,last);
}
Ну, а вот и применение:
int main(int argc, const char * argv[])
{
string s = "abcdefghij";
rot(s.begin(),s.begin()+3,s.end());
cout << s << endl;
}
А теперь самое интересное: все это написано для понимания, и не более того, потому что в стандартной библиотеке есть симпатичный алгоритм rotate, который выполняет левый циклический сдвиг элементов диапазона, так что в нормальной, так сказать, production-программе лучше использовать его...