Случайное значение без повторений в диапазоне от 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;
}
}
Спасибо! |
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>
|
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 будут одинаковыми, то рекурсия будет бесконечной. |
рони,
Спасибо за ответ, но у вас громоздкое решение, возможно оно более оптимальное, но мне не подходит. 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})
}
|
Для целых чисел могу предложить такой вариант еще:
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))
Хотя и для нецелых тоже - главное задать шаг в третьей строке ;) |
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>
|
Храните старые значения в хеше и проверяйте наличие соответствующего ключа. Вот псевдокод:
Код:
var rs = {}; |
with-love-from-siberia,
а что делать если сгенерировалсь число которое было ? генерировать снова и снова ? чем тогда ваш код лучше чем Sweet, или ponyspy,? |
рони, твой скрипт может и хорош, но совершенно нет желания разбираться даже в таком маленьком кусочке творчества человека-обсфукатора. Впредь называй пожалуйста переменные нормально, а сжатие оставь компилеру.)
|
Цитата:
Цитата:
|
| Часовой пояс GMT +3, время: 19:41. |