Показать сообщение отдельно
Старый 12.11.2012, 21:21
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 9  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Сообщение от strangedk Посмотреть сообщение
Код AS3:
var _source:Array = [1,2,3,4,5,6,7,8,9,0];
var _result:Array = [];
 
while (_source.length > 0) {
    _result.push(_source.splice(Math.round(Math.random() * (_source.length - 1)), 1)[0]);
}
Не знаю, более ли этот вариант правильное распределение даёт, чем предыдущие, но сплайсить массив n раз дорого - сложность почти n * n + затраты на выделение памяти и сборку мусора.
Math.round(Math.random() * (_source.length - 1)) вроде бы эквивалентно int(Math.random() * _source.length), не?
Как написать то же самое (1 в 1), но без сплайса и без создания другого массива (линейная сложность ):
Код AS3:
public static function shuffle(array:Array):void {
	var length:int = array.length;
	while (length > 0) {
		var index:int = int(Math.random() * length);
		var value:int = array[index];
 
		// Элемент выбран, появилась дырка - заделываем элементом с условного конца
		// и у нас снова ровный массив из оставшихся элементов
		array[index] = array[length - 1];
 
		// Кидаем выбранный элемент в текущий условный конец массива - там выборки уже не будет
		// Т.е. слева у нас старый массив - справа строим новый
		array[length - 1] = value;
 
		// Левый (исходный) массив поубавился
		length--;
	}
}


Последний раз редактировалось expl; 12.11.2012 в 21:32.