Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.03.2014, 18:55
Интересующийся
Отправить личное сообщение для ponyspy Посмотреть профиль Найти все сообщения от ponyspy
 
Регистрация: 27.09.2013
Сообщений: 15

Случайное значение без повторений в диапазоне от min до max
Привет!

Я столкнулся с проблемой генерации случайных значений, все что нашел в интернете по этой теме не решает проблему повторяющихся значений при многократном вызове.

Вот мой вариант, но он как-то странно работает, в некоторых ситуация, случаются повторения.

var random = {
		randNum: 0, randNumOld: 0,
		oMin: 0, oMax: 0,

		getRandomInt: function (min, max) {
			random.oMin = min;
			random.oMax = max;

			random.randNum = Math.floor(Math.random() * (max - min + 1)) + min;
			if (random.randNum == random.randNumOld) random.getRandomInt(random.oMin, random.oMax);
			random.randNumOld = random.randNum;

			return random.randNum;
		}
	}


Спасибо!
Ответить с цитированием
  #2 (permalink)  
Старый 25.03.2014, 19:18
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

ponyspy,
<script>
function rund(e, f) {
        function d(b) {
            for (var a = b.length - 1; 0 < a; a--) {
                var c = Math.floor(Math.random() * (a + 1)),
                    d = b[c];
                    b[c] = b[a];
                    b[a] = d
            }
            return b
        }
        var a = [],
            c = [];
        for (i = 0; i < e; i++) a[i] = i + f;
        d(a);
        return function () {
            var b = a.shift();
            c.push(b);
            1 == a.length && (d(c), a = a.concat(c), c = []);
            return b
        }
    };

 var len = 5,
     min = 10,
     z = rund(len,min),
     i;

 for (i = 0; i < 40; i++) {
     document.write(z()+' '); //для примера
 }
</script>
Ответить с цитированием
  #3 (permalink)  
Старый 25.03.2014, 19:48
Профессор
Отправить личное сообщение для Sweet Посмотреть профиль Найти все сообщения от Sweet
 
Регистрация: 16.03.2010
Сообщений: 1,618

ponyspy, random.randNum, random.oMin и random.oMax - не нужны. Но это не главное. В 10 строчке, если число совпадает с предыдущим, то делается ещё одна попытка получить число. И если опять числа совпадают, то всё ровно возращается это значение. Там нужно добавить return, тогда вызов будет рекурсивным:
var random = {
    randNumOld: 0,
 
    getRandomInt: function (min, max) {
        var randNum = Math.floor(Math.random() * (max - min + 1)) + min;

        if (randNum == random.randNumOld) return random.getRandomInt(min, max);
        random.randNumOld = randNum;
 
        return randNum;
    }
};
Толь о учти, что если min и max будут одинаковыми, то рекурсия будет бесконечной.
Ответить с цитированием
  #4 (permalink)  
Старый 25.03.2014, 23:55
Интересующийся
Отправить личное сообщение для ponyspy Посмотреть профиль Найти все сообщения от ponyspy
 
Регистрация: 27.09.2013
Сообщений: 15

рони,
Спасибо за ответ, но у вас громоздкое решение, возможно оно более оптимальное, но мне не подходит.

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

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

Вызов происходит внутри функции обработчика, которая срабатывает по событию клик.

Вот так выглядит функция обработчик:
function generatePoster () {
		var hide_items = $('.hide').size() - 1;
		var rand_items = random.getRandomInt(0, hide_items);
		var rand_radius = random.getRandomInt(200, 600);

		var atr = $('.hide').eq(rand_items).attr('src');
		$('.image').attr('src', atr);

		$('.main_poster_cal').hide();
		$('.main_poster_cal').eq(rand_items).show();

		$('.round').animate({
			width: rand_radius,
			height: rand_radius
		}, {duration: 400, queue: false})
	}
Ответить с цитированием
  #5 (permalink)  
Старый 26.03.2014, 00:12
Аватар для BETEPAH
Профессор
Отправить личное сообщение для BETEPAH Посмотреть профиль Найти все сообщения от BETEPAH
 
Регистрация: 23.06.2011
Сообщений: 1,165

Для целых чисел могу предложить такой вариант еще:
function severalRandom(min, max, num) {
	var i, arr = [], res = [];
	for (i = min; i <= max; i++ ) arr.push(i);
	for (i = 0; i < num; i++) res.push(arr.splice(Math.floor(Math.random() * (arr.length)), 1)[0])
	return res;
}
alert(severalRandom(4, 40, 5))

Хотя и для нецелых тоже - главное задать шаг в третьей строке

Последний раз редактировалось BETEPAH, 26.03.2014 в 00:15.
Ответить с цитированием
  #6 (permalink)  
Старый 26.03.2014, 01:29
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

ponyspy,
и что тут
Сообщение от ponyspy
громоздкое решение
?
<!DOCTYPE HTML>
<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <style type="text/css">
  .round{background:#FFA500;width:0px;height:0px;padding:8px;border-radius:4px}
  .image{width:100%;height:100%}
  .hide{display:none}
  </style>
  <script>
  $(function (){
   $('#test').click(generatePoster);
    function rund(e, f) {
        function d(b) {
            for (var a = b.length - 1; 0 < a; a--) {
                var c = Math.floor(Math.random() * (a + 1)),
                    d = b[c];b[c] = b[a];b[a] = d }
            return b}
        var a = [],c = [];
        for (i = 0; i < e; i++) a[i] = i + f;d(a);
        return function () {
            var b = a.shift();c.push(b);
            1 == a.length && (d(c), a = a.concat(c), c = []);
            return b
        }
    };
    var hide_items = $('.hide').size();
	var rand_items = rund(hide_items, 0);
	var rand_radius = rund(400, 200);
    function generatePoster () {
        //var item = rand_items();
        //var radius  = rand_radius(); item и radius использовать если нужны одинаковые значения
		var atr = $('.hide').eq(rand_items()).attr('src');
		$('.image').attr('src', atr);
		//$('.main_poster_cal').hide().eq(rand_items()).show();
		$('.round').css("background-color", "#"+Math.ceil(Math.random()*16777214).toString(16))
        .animate({
			width: rand_radius(),
			height: rand_radius()
		}, {duration: 400, queue: false})
	}
})

  </script>
</head>

<body>
  <input id="test" type="button" value="generate">
  <div class="round">
  <img class="image"  src="" alt="">
  </div>
  <img class="hide"  src="http://cache.foxsaver.com/thumbnails/2009/06/17/1410246630t.jpg" alt="">
  <img class="hide"  src="http://mindfulreiki.co.uk/wp-content/uploads/2012/12/flower-300x300.png" alt="">
  <img class="hide"  src="http://www.fragrantica.ru/images/avatariru/t.38016.jpg" alt="">
  <img class="hide"  src="http://www.birdz.sk/uc/av/e/c/ec9fecaceb74d24679b73295e80f10ca.jpg" alt="">
  <img class="hide"  src="http://cs304505.vk.me/v304505947/5fe0/uWP57ucJ5cM.jpg" alt="">
  <img class="hide"  src="http://s018.radikal.ru/i519/1202/62/8856baf46906.jpg" alt="">
</body>

</html>

Последний раз редактировалось рони, 26.03.2014 в 18:09.
Ответить с цитированием
  #7 (permalink)  
Старый 26.03.2014, 02:56
Профессор
Отправить личное сообщение для with-love-from-siberia Посмотреть профиль Найти все сообщения от with-love-from-siberia
 
Регистрация: 14.12.2009
Сообщений: 155

Храните старые значения в хеше и проверяйте наличие соответствующего ключа. Вот псевдокод:
Код:
var rs = {};

...

// сгенерировать случайное целок число на интервале [a, b]
var r = randomInt(a, b);

// проверить, что этого числа еще не было
if ( ! rs[r] ) {
    // запомнить число...
    rs[r] = 1;
    // .. и вернуть его
    return r;
}
Полагаю, Вы знаете, что делать дальше, когда весь массив случайных чисел из интервала [a, b] будет исчерпан.
Ответить с цитированием
  #8 (permalink)  
Старый 26.03.2014, 09:15
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

with-love-from-siberia,
а что делать если сгенерировалсь число которое было ? генерировать снова и снова ? чем тогда ваш код лучше чем
Sweet, или
ponyspy,?
Ответить с цитированием
  #9 (permalink)  
Старый 26.03.2014, 13:21
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,480

рони, твой скрипт может и хорош, но совершенно нет желания разбираться даже в таком маленьком кусочке творчества человека-обсфукатора. Впредь называй пожалуйста переменные нормально, а сжатие оставь компилеру.)
__________________
29375, 35
Ответить с цитированием
  #10 (permalink)  
Старый 26.03.2014, 14:09
Профессор
Отправить личное сообщение для with-love-from-siberia Посмотреть профиль Найти все сообщения от with-love-from-siberia
 
Регистрация: 14.12.2009
Сообщений: 155

Сообщение от рони
а что делать если сгенерировалсь число которое было ?
Я лично не знаю. Все зависит от поставленной задачи. Как я уже заметил,
Сообщение от with-love-from-siberia
Полагаю, Вы знаете, что делать дальше, когда весь массив случайных чисел из интервала [a, b] будет исчерпан.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выводить значение раньше переменных Гробовщик Общие вопросы Javascript 11 10.09.2013 08:42
как правильно задавать значение min, max в Slider UI Серёжа Шевченко Общие вопросы Javascript 1 28.11.2012 17:15