Перемешивание элементов в массиве
Перемешивание элементов в массиве

Перемешивание элементов в массиве

25 апреля 2023       151 просмотр

Размышляя под рюмку чая о всяком один товарищ предложил мне подумать, мол — вот есть у тебя две груши в массиве 25 чисел, расположены по-порядку. Представь, что тебе нужно заморозить свой сон и съесть его их случайным образом перемешать. Что делать будешь? Только не гугли!

Ок, вызов брошен, и, как только у меня появилось время сесть за кудахтер и помучать себя и клавиатуру — я решил глянуть порнхаб размять пальцы и моск.

Первая моя мысль была — бахнуть пивка дважды воспользоваться рандомайзером — сгенерировать индекс массива, сгенерировать число, но все мы знаем, что такое рандом, так что, едва дописав первый rand, я остановился и задумался. Числа ведь не должны повторяться...

Ок, может тогда запоминать числа, которые уже сгенерированы? Не, бред какой-то... Должно быть решение более лаконичное и не такое громоздкое в плане говнокода.

Ок, возьмём ручку и бумажку, чтобы не было соблазна, и подумаем что можно сделать из говна и веток наших исходных данных. Массив уже заполнен? Заполнен. По-порядку? Ну да. Значит значение индекса равно или соответствует значению в массиве. Чтож, давайте грязно этим воспользуемся!

Получается мне нужно просто перемешивать индексы, а то, что значения идут по порядку только облегчает задачу. Будем их свапать, используя рандом. Ок, а сколько раз это нужно сделать? Ну, логика подсказывает, что как минимум столько, сколько элементов в массиве. Ок, зная это уже можно садиться обратно на любой из двух стульев за кудахтер.

#include <iostream>
#include <cstdlib>
#include <ctime>//нужно для рандома

using namespace std;

void kruchuverchu(int arr[], int n)//что ж приступим, вот наш массив, вот количество чисел
{
	srand(time(NULL));//врубаем рандом
	for (int i = n - 1; i > 0; i--)//пойдём от большего значения, так перемешивается лучше
	{
		int j = rand() % (i + 1);//тут всё очевидно, берём побольше, чтобы задействовать весь массив
		swap(arr[i], arr[j]);//меняем местами
	}
}

int main()
{
	cout << "vvedite kolichestvo chisel" << endl;//введём
	int n;//сколько
	cin >> n;//у нас чисел
	int arr[n];//создаем
	for (int i = 0; i < n; i++)//и заполняем массив
	{
		arr[i] = i + 1;//ну мы же в повседневности не от нуля считаем )
	}
	kruchuverchu(arr, n);//теперь перемешиваем
	for (int i = 0; i < n; i++)//и выводим наш перемешанный
	{
		cout << arr[i] << " ";//массив в окно консоли
	}
	cout << endl;
	return 0;
	system("pause");
}

upd Кстати, загуглил сейчас, оказывается такой алгоритм, когда от большего индекса к меньшему перемещаются случайные оставшиеся значения — называется алгоритм Фишера-Йетса. И гуглится довольно легко.