Как циклически сдвинуть массив в C#?
Здравствуйте! Не могли бы помочь, как циклически сдвинуть массив в C# на k элементов?
существуют два принципиально разный подхода (сейчаc лень, но можете порыться, на форуме я как-то приводил примеры кода, правда, на Delphi):
— однопроходный. Каждый элемент сразу сдвигаем на столько элементов, на сколько надо. Это очень эффективно. Но тут возникают сложности, т.к. достатночно муторно вычислить, какой элемент с каким надо менять местами.
— циклический. Любой сдвиг на K элементов это К сдвигов на один элемент. А сдвиг на один элемент — это алгоритмически крайне просто.
Вот пример решения на основании второго подхода:
const int n = 5 ;
int [ ] a = new int [ n ] { 1 , 2 , 3 , 4 , 5 } ;
Console. WriteLine ( «Исходный массив:» ) ;
for ( int i = 0 ; i < n; ++i )
Console. Write ( » \t » + a [ i ] ) ;
Console. WriteLine ( ) ;
Console. WriteLine ( «Введите k» ) ;
int k = Convert. ToInt16 ( Console. ReadLine ( ) ) ;
for ( int i = 0 ; i < k; ++i )
{
int aLast = a [ n -1 ] ;
for ( int j = n -1 ; j> 0 ; j— )
a [ j ] = a [ j -1 ] ;
a [ 0 ] = aLast;
}
Console. WriteLine ( «Новый массив: » ) ;
for ( int i = 0 ; i < n; ++i )
Console. Write ( » \t » + a [ i ] ) ;
Console. WriteLine ( ) ;
Console. ReadKey ( ) ;
Похожие статьи
- Работа с двумерными массивами (матрицами) средствами Delphi
- Динамические массивы Turbo Pascal
- Использование нетипизированного указателя для передачи массива
- Запись данных в файла из массив с помощью FileStream
- Как перемешать массив, заполненный английским алфавитом?
- Как создать двумерный динамический массив?
- Класс, который ищет совпадение в массиве
- Умножение матриц
- Получить из текста строки, и занести их в массив
- Как использовать цвета в массиве
Циклический сдвиг массива влево и вправо
Напишите программу, которая в массиве целых чисел длины m+n, рассматриваемом как соединение двух его частей – начала длины m и конца длины n, обменивает начало и конец, не используя дополнительных массивов.
- элемент 4 (начало второго массива) надо поставить на место элемента 1 (начало первого массива). Значит после перемещения – мы потеряем число 1.
- хотелось бы сразу записать число 1 на место во втором массиве, но его правильное место занимает число 6 и при попытке записать – мы сотрем его…
Идеи как это делать:
1) можно попробовать сразу поставить на место первый массив, переместив на его место элементы второго. В результате получится что-то такое:
6 7 8 4 5 1 2 3
теперь остается переставить m и m-n элементов внутри второго массива, но при рассмотрении на этом примере становится ясно, что эта задача не проще чем изначальная – возникают ровно те же проблемы.
2) перестановка частей массива – это циклический сдвиг массива на m элементов влево. Опишем функцию, выполняющую сдвиг на 1 элемент влево и вызовем ее m раз.
Для сдвига массива на одни элемент влево:
- запомним значение первого элемента;
- сдвинем все остальные влево, по очереди;
- запишем в конец массива значение первого элемента (ведь сдвиг циклический);
#include #include #include #include void read_array(int n, int** values) < for (int i = 0; i < n; ++i) < printf("values[%d] = ", i); scanf("%d", &((*values)[i])); >> void print_array(int n, int* values) < for (int i = 0; i < n; ++i) < printf("values[%d] = %d\n", i, values[i]); >> void shift_left(int *a, int n) < if (0 == n) return; int first = a[0]; for (int i = 1; i < n; ++i) a[i-1] = a[i]; a[n-1] = first; >void shift_left_on(int *a, int n, int shift_size) < for (int i = 0; i < shift_size; ++i) < shift_left(a, n); >> int main()
Задача (сдвиг вправо):
Напишите программу, которая вводит с клавиатуры массив целых чисел и циклически сдвигает элементы массива вправо на k позиций. Число k вводится с клавиатуры.
Если есть массив из 5 элементов 1 2 3 4 5 , то сдвиг вправо на 2 позиции это 4 5 1 2 3 .
Не сложно заметить, что такой же результат получился бы при сдвиге влево на 3 позиции.
Итого, сдвиг в массиве из N элементов вправо на K позиций даст тот же результат, что сдвиг влево на N-K позиций.
Кроме того, можно учесть циклический сдвиг, то есть если в этом же массиве выполнить сдвиг на 6 , 11 или 101 позиций – то результат будет аналогичен сдвигу на 1 позицию.
void shift_right_on(int *a, int n, int shift_size) < shift_size = shift_size % n; shift_size = n - shift_size; for (int i = 0; i < shift_size; ++i) < shift_left(a, n); >>
Результаты работы программы:
Сдвинуть элементы массива на k позиций
пусть а — это массив для сдвига, а size_array — его размер и пусть массив будет целочисленный.
int tmp1, tmp2; tmp1 = a[0]; tmp2 = a[1]; for (int i = 0; i < size_array-2; i++) a[i] = a[i+2]; a[size_array-2] = tmp1; a[size_array-1] = tmp2;
если нужно сдвинуть на какое то другое кол-во позиций, то обычно применяют последовательный сдвиг. Ещё можно завести массив, равный сдвигу, скопировать туда начальные элементы (memcpy) остальные элементы сдвинуть (memmove) и скопировать с дополнительно массива назад элементы в конец исходного массива.,
UPD: здесь есть очень интересные объяснения, как делать сдвиг.
Как сдвинуть массив вправо c
Здравствуйте! Не могли бы помочь, как циклически сдвинуть массив в C# на k элементов. Исходный массив A=(1,2,3,4,5), а сдвинутый вправо на 2 позиции будет A=(4,5,1,2,3)
const int n = 5; int[] a = new int[n] < 1, 2, 3, 4, 5 >; int[] c; int[] p = new int[n]; Console.WriteLine("Исходный массив:"); for (int i = 0; i < n; ++i) Console.Write("\t" + a[i]); Console.WriteLine(); Console.WriteLine("Введите k"); int k = Convert.ToInt16(Console.ReadLine()); for (int i = 0; i < k; ++i) p[i] = a[n - k + i]; for (int i = n - k; i < 0; --i) a[i + k] = a[i]; for (int i = 0; i < k; ++i) a[i] = p[i]; Console.WriteLine("Новый массив: "); for (int i = 0; i < n; ++i) Console.Write("\t" + a[i]); Console.WriteLine(); Console.ReadKey();
Получается только половина действия, т.е. хвост массива сдвигается вперед, а остальные элементы стоят на месте: A=(4,5,3,4,5). Ошибка где-то в цикле, получается 2-й for ничего не делает.
Искала в предыдущих темах, но такого не нашла ответа. Может быть кто-нибудь знает?
Форумчанин Подтвердите свой е-майл
Регистрация: 31.03.2008
Сообщений: 179
. int[] a = new int[10] ; int[] b = new int[10]; int offset = 3; for (int i = 0; i < a.Length; i++) < b[i] = (i + offset) % a.Length; >.
Регистрация: 09.01.2008
Сообщений: 26,238
существуют два принципиально разный подхода (сейчаc лень, но можете порыться, на форуме я как-то приводил примеры кода, правда, на Delphi):
- однопроходный. Каждый элемент сразу сдвигаем на столько элементов, на сколько надо. Это очень эффективно. Но тут возникают сложности, т.к. достатночно муторно вычислить, какой элемент с каким надо менять местами.
- циклический. Любой сдвиг на K элементов это К сдвигов на один элемент. А сдвиг на один элемент - это алгоритмически крайне просто.
Вот пример решения на основании второго подхода:
const int n = 5; int[] a = new int[n] < 1, 2, 3, 4, 5 >; Console.WriteLine("Исходный массив:"); for (int i = 0; i < n; ++i) Console.Write("\t" + a[i]); Console.WriteLine(); Console.WriteLine("Введите k"); int k = Convert.ToInt16(Console.ReadLine()); for (int i = 0; i < k; ++i) < int aLast = a[n-1]; for (int j = n-1; j>0; j--) a[j] = a[j-1]; a[0] = aLast; > Console.WriteLine("Новый массив: "); for (int i = 0; i < n; ++i) Console.Write("\t" + a[i]); Console.WriteLine(); Console.ReadKey();
p.s. akasex, молодца! Опередил! впрочем, с дополнительным массивом это просто. Гораздо интереснее решить задачу БЕЗ дополнительного массива!
Последний раз редактировалось Serge_Bliznykov; 21.10.2010 в 21:48 .
| Serge_Bliznykov |
| Посмотреть профиль |
| Найти ещё сообщения от Serge_Bliznykov |