Перемешивание элементов в массиве
Размышляя под рюмку чая о всяком один товарищ предложил мне подумать, мол — вот есть у тебя две груши в массиве 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 Кстати, загуглил сейчас, оказывается такой алгоритм, когда от большего индекса к меньшему перемещаются случайные оставшиеся значения — называется алгоритм Фишера-Йетса. И гуглится довольно легко.