Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Генератор случайных чисел без повтора (http://www.flasher.ru/forum/showthread.php?t=134881)

gauss 11.01.2010 14:06

Генератор случайных чисел без повтора
 
Здравствуйте, пользователи форума flasher.ru!
Хочу задать вопрос и надеюсь на ваш ответ:)
Как создать генератор случайных чисел, я знаю.
Но мне непонятно, как сделать, чтобы числа не повторялись?:(

Hauts 11.01.2010 14:12

Если у вас не дробные случайные числа, то записывайте "1" (или что угодно) в массив, в поле с индексом нового случайного числа. Если, когда вы получаете новое число, вы обнаруживаете, что в массиве под этим индексом уже есть запись, то генерите еще раз число, пока в массиве не останется пустых элементов (если задан диапозон случайных чисел). Это проще, чем сохранять в массив новое случайное число, и потом каждое следующее сравнивать со всем массивом.

Если дробные числа, то домножайте их на несколько порядков, чтобы получились целые.

Я не уверен, что такой способ будет оптимальным, может вам еще что-нибудь подскажут. :)

gauss 11.01.2010 14:15

Вы не совсем поняли
Генератор встроен в функцию, которая повторяется раз в секунду, т. е. раз в секунду генерируется новое число. Надо чтобы ОДНО число повторялось ОДИН раз. Например, если есть пять чисел, то они шли так: 1 2 3 4 5 или 3 2 4 5 1.

udaaff 11.01.2010 14:19

Создайте массив [ 1, 2, 3, 4, 5 ]. И выбирайте из него числа. Выбранное, удаляйте из массива через Array#splice().

gauss 11.01.2010 14:22

Я начинающий пользователь и ПОКА ЧТО мало что понимаю в массивах:(
Нет конечно я знаю как создать:)
Но если Вы скинете код, то мои познания увеличатся!:):D

Hauts 11.01.2010 14:25

Код AS1/AS2:

var randoms = [];
function getRandomNum() {
        var rnd = Math.floor(Math.random()*1000);
        if (randoms[rnd] != true) {
                randoms[rnd] = true;
                return rnd;
        } else {
                return getRandomNum();
        }
}
for (var k = 0; k<100; k++) {
        trace(getRandomNum());
}

Примерно такое я имел в виду.

gauss 11.01.2010 14:27

13:26
проверяю код...

Добавлено через 2 минуты
13:28
Ура!!! Всё работает!!!
Спасибо всем, кто мне помог!
Правда, есть небольшие нюансы, но их я додумаю сам!

Hauts 11.01.2010 14:35

Код AS1/AS2:

var randoms = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
function getRandomNum() {
        var rnd = Math.floor(Math.random()*randoms.length);
        var toReturn = randoms[rnd];
        randoms.splice(rnd,1);
        return toReturn;
}
for (var k = 0; k<20; k++) {
        trace(getRandomNum());
}

Это способ от udaaff.

Вот сравнение скорости:
Код AS1/AS2:

var randoms = [];
function getRandomNum() {
        var rnd = Math.floor(Math.random()*1000);
        if (randoms[rnd] != true) {
                randoms[rnd] = true;
                return rnd;
        } else {
                return getRandomNum();
        }
}
var t1 = getTimer();
for (var k = 0; k<256; k++) {
        trace(getRandomNum());
}
trace("getRandomNum1 "+(getTimer()-t1)+"ms");
var randoms2 = [];
for (var k = 0; k<=256; k++) {
        randoms2[k] = Math.floor(Math.random()*1000);
}
function getRandomNum2() {
        var rnd = Math.floor(Math.random()*randoms2.length);
        var toReturn = randoms2[rnd];
        randoms2.splice(rnd,1);
        return toReturn;
}
var t2 = getTimer();
for (var k = 0; k<256; k++) {
        trace(getRandomNum2());
}
trace("getRandomNum2 "+(getTimer()-t2)+"ms");

У меня получилось:

getRandomNum1 3ms
getRandomNum2 40ms

Только в моем способе из-за рекурсии могут быть проблемы. Если я в чем-то ошибаюсь — поправьте :)

gauss 11.01.2010 14:38

Увы, не получилось...:(:confused:
А как сделать, чтобы згачения не выводились, а их принимало текстовое поле?:)
Помогите новичку плиз!:):)

udaaff 11.01.2010 14:39

Цитата:

Сообщение от Hauts (Сообщение 878221)
Код AS1/AS2:

var randoms = [];
function getRandomNum() {
        var rnd = Math.floor(Math.random()*1000);
        if (randoms[rnd] != true) {
                randoms[rnd] = true;
                return rnd;
        } else {
                return getRandomNum();
        }
}
for (var k = 0; k<100; k++) {
        trace(getRandomNum());
}

Примерно такое я имел в виду.

Этот способ нужно применять если количество возможных значений много больше чем возможное количество сгенерированных случайных чисел. Иначе можно превысить 256 уровней рекурсии. Даже без превышения будет много лишних вычислений.

Если значений не много, то лучше из массива выбирать:
Код AS1/AS2:

var array:Array = [ 1, 2, 3, 4, 5 ];
 
function getRandom():Number
{
        return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
 
var length:Number = array.length;
for (var i:Number = 0; i < length; i++)
{
        trace(getRandom());
}

upd: мой способ меня уже опередил :)


Часовой пояс GMT +4, время: 02:35.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.