У меня может быть альтернативное решение для вращения массива в строке. В отличие от старого трюка с перестановкой наборов элементов, как предлагалось ранее, этот подход работает следующим образом:
Инициализация:
(Примечание q = величина смещения влево, n = длина массива)
- Определите первый элемент источника, который расположен в x1 = q% n
- Элемент назначения имеет х2 = 0
- char, ch1, является элементом ar [x1]
- char, ch2, является элементом ar [x2]
Цикл от i = 0 до n-1, где n = длина массива
- Перезаписать целевой элемент ar [x2] с помощью ch1
- Set ch1 = ch2
- Set x1 = x2
- Set x2 = x2 - q
- Если x2 отрицательно из-за вышеуказанного вычитания, добавьте к нему n
- ch2 = ar [x2]
Следующее может помочь объяснить, как это работает.
Пример, повернуть влево на 2 символа:
a b c d e f g
c d e f g a b
x1 ch1 x2 ch2
2 c 0 a
0 a 5 f
5 f 3 d
3 d 1 b
1 b 6 g
6 g 4 e
4 e 2 c
Как видите, для этого требуется не более n итераций, поэтому алгоритм линейного времени также вращает inline (не требует дополнительной памяти, кроме нескольких временных переменных).
Вот функция, которая реализует описанный выше алгоритм, поэтому вы можете попробовать его:
void rotate(char *ar, int q)
{
if (strlen(ar) < 2)
{
return;
}
if (q <= 0)
{
return;
}
char ch1;
char ch2;
int x1;
int x2;
int i;
int n;
n = strlen(ar);
q %= n;
if (q == 0)
{
return;
}
x1 = q;
ch1 = ar[x1];
x2 = 0;
ch2 = ar[x2];
for (i=0;i<n;i++)
{
ar[x2] = ch1;
ch1 = ch2;
x1 = x2;
x2 -= q;
if (x2 < 0)
{
x2 += n;
}
ch2 = ar[x2];
}
}