Перейти к содержимому

Как сдвинуть массив вправо c

  • автор:

Как циклически сдвинуть массив в 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, обменивает начало и конец, не используя дополнительных массивов.

  1. элемент 4 (начало второго массива) надо поставить на место элемента 1 (начало первого массива). Значит после перемещения – мы потеряем число 1.
  2. хотелось бы сразу записать число 1 на место во втором массиве, но его правильное место занимает число 6 и при попытке записать – мы сотрем его…

Идеи как это делать:

1) можно попробовать сразу поставить на место первый массив, переместив на его место элементы второго. В результате получится что-то такое:

6 7 8 4 5 1 2 3

теперь остается переставить m и m-n элементов внутри второго массива, но при рассмотрении на этом примере становится ясно, что эта задача не проще чем изначальная – возникают ровно те же проблемы.

2) перестановка частей массива – это циклический сдвиг массива на m элементов влево. Опишем функцию, выполняющую сдвиг на 1 элемент влево и вызовем ее m раз.

Для сдвига массива на одни элемент влево:

  1. запомним значение первого элемента;
  2. сдвинем все остальные влево, по очереди;
  3. запишем в конец массива значение первого элемента (ведь сдвиг циклический);

#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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *