Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перемешивание значений в массиве 
:(
    Опции темы
lavrnn
Дата 16.6.2009, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 23.2.2009

Репутация: нет
Всего: нет



Решил изучать net ... и использовать.

Создал одномерный массив из 36 элементов. Могу ли я реализовать перемешивание массива стандартными методами, либо нужно писать отдельный функционал?

PM MAIL   Вверх
mihryak
Дата 17.6.2009, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



функции готовой такой нет, здесь вам не пхп smile

зато с linq это можно сделать в полторы строчки:
Код

Random random = new Random();
int[] sourceArray = new int[] {0, 1, 2, 3, 4, 5, 6};
int[] randomArray = sourceArray.OrderBy(i => random.Next()).ToArray();


Это сообщение отредактировал(а) mihryak - 17.6.2009, 00:29
PM MAIL ICQ   Вверх
dazy
Дата 17.6.2009, 07:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 15.9.2006

Репутация: 1
Всего: 8



А random может быть любым? Не только от 0 до 6? 
Если можно пару камментов, как это работает, что-то не совсем понятен принцип.
PM MAIL   Вверх
Idsa
Дата 17.6.2009, 07:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(dazy @  17.6.2009,  11:03 Найти цитируемый пост)
Если можно пару камментов, как это работает, что-то не совсем понятен принцип. 

При сортировке для каждого элемента будет использован rand.Next() в качестве приоритета. А так как rand.Next() генерирует псевдослучайные числа, на выходе получим перемешивание массива.

Конечно, использовать сортировку для перемешивания - не самый оптимальный подход... но для указанных lavrnn 36 элементов - самое то.

Это сообщение отредактировал(а) Idsa - 17.6.2009, 07:26


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
dazy
Дата 17.6.2009, 08:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 15.9.2006

Репутация: 1
Всего: 8



Мне не совсем понятно, как используется чистый рандом, без приведения к формату массива. 

Я самого механизма не понимаю, т.е. если на одной итерации random будет равен 3, а на другой 100, а элементов массива всего 36, это не помешает перемешиванию? Не будет выхода за границы?
Т.е. как именно вот эта штука работает - sourceArray.OrderBy(i => random.Next()).ToArray(); И почему random может быть любым числом?

Правильно я понял, что точно таким же образом можно можно перемешать любой массив, хоть со строками, хоть с объектами?

Тогда уточним вопрос ТС, а как правильно перемешать массив в общем случае, а не только всего из 36 элементов?
PM MAIL   Вверх
Rififi
Дата 17.6.2009, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 5
Всего: 36



dazy
как правильно перемешать массив в общем случае
например так, как это делается в std::random_shuffle
PM MAIL   Вверх
Idsa
Дата 17.6.2009, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 14
Всего: 62



Цитата(dazy @  17.6.2009,  12:08 Найти цитируемый пост)
Я самого механизма не понимаю, т.е. если на одной итерации random будет равен 3, а на другой 100, а элементов массива всего 36, это не помешает перемешиванию?

Для каждого элемента rand.Next() высчитывается один раз, поэтому не помешает.

Цитата(dazy @  17.6.2009,  12:08 Найти цитируемый пост)
Правильно я понял, что точно таким же образом можно можно перемешать любой массив, хоть со строками, хоть с объектами?

Да, конечно. Это нечто вроде упрощенного IComparer.

Цитата(dazy @  17.6.2009,  12:08 Найти цитируемый пост)
Тогда уточним вопрос ТС, а как правильно перемешать массив в общем случае, а не только всего из 36 элементов? 

Как угодно smile
Первое, что пришло в голову:
1. Длина массива n. Берем переменную k = n / 2
2. Цикл от 0 до k - 1. В ходе каждой итерации переставляем rand.Next() и rand.Next() элементы (где rand ограничен длиной массива).
3. Если длина массива < 5 - реализуем ручную перестановку.

Цитата(Rififi @  17.6.2009,  12:15 Найти цитируемый пост)
например так, как это делается в std::random_shuffle 

И как же? smile


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
mihryak
Дата 17.6.2009, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



Цитата(dazy @  17.6.2009,  09:08 Найти цитируемый пост)
Я самого механизма не понимаю, т.е. если на одной итерации random будет равен 3, а на другой 100, а элементов массива всего 36, это не помешает перемешиванию? Не будет выхода за границы?
Т.е. как именно вот эта штука работает - sourceArray.OrderBy(i => random.Next()).ToArray(); И почему random может быть любым числом?

Правильно я понял, что точно таким же образом можно можно перемешать любой массив, хоть со строками, хоть с объектами?
Тогда уточним вопрос ТС, а как правильно перемешать массив в общем случае, а не только всего из 36 элементов? 

Работает так - каждому элементу массива сопоставляется произвольное случайное число, т.е. вместо элемента появляется пара "элемент-случайное число", а после они сортируются по этому произвольному числу. А какое именно оно будет, из какого диапазона - совершенно не важно, даже интуитивно кажется, что чем хаотичней, тем лучше, так что Random параметризовать  не обязательно.

Работать будет с любым массивом, независимо от типа элементов, везде суть будет та же - абстрактному элементу сопоставляется случайное целочисленное значение.

В общем случае можно написать цикл, пробегающий по всему массиву, на каждой итерации получать рандомный индекс из диапазона [0, n), менять местами текущий элемент итерации на элемент с полученным индексом. Работать будет надёжно, про кол-во элементов и потребляемую память можно будет не думать.

Но если позволяет задача (не слишком большое количество элементов и эпизодическая потребность в их перемешивании), я бы воспользовался способом из моего первого комментария.

Добавлено @ 09:09
Цитата(Idsa @  17.6.2009,  09:35 Найти цитируемый пост)
Первое, что пришло в голову:
1. Длина массива n. Берем переменную k = n / 2
2. Цикл от 0 до k - 1. В ходе каждой итерации переставляем rand.Next() и rand.Next() элементы (где rand ограничен длиной массива).
3. Если длина массива < 5 - реализуем ручную перестановку.

мне кажется, что этот способ будет не очень хорошо перемешивать, особенно при небольших размеров массива - многие имеют шанс остаться на своём месте

Это сообщение отредактировал(а) mihryak - 17.6.2009, 09:14
PM MAIL ICQ   Вверх
dazy
Дата 17.6.2009, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 15.9.2006

Репутация: 1
Всего: 8



Цитата

Работает так - каждому элементу массива сопоставляется произвольное случайное число...


Вроде дошло, спасибо за развернутый ответ!
PM MAIL   Вверх
lavrnn
Дата 17.6.2009, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 23.2.2009

Репутация: нет
Всего: нет



mihryak

Очень вам признателен! Благодарю!

Не уверен, что это самый оптимальный вариант, но пока - в качестве заглушки, очень помогло!
PM MAIL   Вверх
Экскалупатор
Дата 17.6.2009, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



lavrnn, а почему бы сразу не использовать списки?
PM MAIL ICQ   Вверх
mihryak
Дата 17.6.2009, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



Цитата(Экскалупатор @  17.6.2009,  18:06 Найти цитируемый пост)
а почему бы сразу не использовать списки? 

а чем они помогут в решении задачи?

Цитата(lavrnn @  17.6.2009,  17:02 Найти цитируемый пост)
Не уверен, что это самый оптимальный вариант, но пока - в качестве заглушки, очень помогло

вот решение с обменом занчениями со случайным индексом, не уверен, что оно оптимально, но по меньшей мере имеет сложность O(N), в отличие от linq'шного OrderBy
Код

        private static void ShuffleArray<T>(T[] array)
        {
            Random r = new Random();
            for (int i = 0; i < array.Length; i++)
            {
                int randomIndex = r.Next(array.Length);
                T temp = array[i];
                array[i] = array[randomIndex];
                array[randomIndex] = temp;
            }
        }
Код

            int[] array = new int[] {0 ,1, 2, 3, 4, 5, 6};
            ShuffleArray(array);

PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0747 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.