Случайное значение без повторений в диапазоне от 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, время: 09:16. |