математическое случайное число без повторения предыдущего числа - PullRequest
8 голосов
/ 08 июля 2011

Не могу найти ответ на этот вопрос, скажем, у меня есть:

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);

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

Ответы [ 9 ]

10 голосов
/ 08 июля 2011

Есть несколько способов достичь этого.

Решение A: Если диапазон чисел невелик (скажем, меньше 10), вы можете просто отслеживать числа, которые вы уже сгенерировали. Затем, если вы сгенерируете дубликат, откажитесь от него и сгенерируйте другое число.

Решение B: Предварительно сгенерируйте случайные числа, сохраните их в массив, а затем пройдитесь по массиву. Вы можете сделать это, взяв числа 1,2,...,n и затем перемешивая их.

shuffle = function(o) {
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;

setInterval(function() {
    $('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);

Решение C: Следите за числами, доступными в массиве. Случайно выбрать номер. Удалить номер из указанного массива.

var randnums = [0,1,2,3,4,5,6];

setInterval(function() {
    var m = Math.floor(Math.random()*randnums.length);
    $('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
    randnums = randnums.splice(m,1);
}, 300);
3 голосов
/ 08 июля 2011

Вы, кажется, хотите получить неповторяющееся случайное число от 0 до 6, так что оно похоже на ответ Цкуцци:

var getRand = (function() {
    var nums = [0,1,2,3,4,5,6];
    var current = [];
    function rand(n) {
        return (Math.random() * n)|0;
    }
    return function() {
      if (!current.length) current = nums.slice();
      return current.splice(rand(current.length), 1);
    }
}());

Возвращает числа от 0 до 6 в случайном порядке. Когда каждый будет нарисован один раз, он начнется снова.

1 голос
/ 08 июля 2011

Мне нравится ответ Нила, хотя он просит прощения.Здесь, в Java, вы все равно получите общее представление.Обратите внимание, что вы попадете в бесконечный цикл, если вы вытянете больше чисел, чем MAX, я мог бы это исправить, но оставил это для ясности.

edit: saw neal добавил цикл while, что прекрасно работает.

public class RandCheck {
    private List<Integer> numbers;
    private Random rand;
    private int MAX = 100;

    public RandCheck(){
        numbers = new ArrayList<Integer>();
        rand = new Random();
    }

    public int getRandomNum(){
        return getRandomNumRecursive(getRand());
    }

    private int getRandomNumRecursive(int num){
        if(numbers.contains(num)){
            return getRandomNumRecursive(getRand());
        } else {
            return num;
        }
    }

    private int getRand(){
        return rand.nextInt(MAX);
    }

    public static void main(String[] args){
        RandCheck randCheck = new RandCheck();

        for(int i = 0; i < 100; i++){
            System.out.println(randCheck.getRandomNum());
        }
    }
}
0 голосов
/ 21 июня 2019

Используйте наборы. Они были введены в спецификации в ES6. Набор - это структура данных, представляющая набор уникальных значений, поэтому не может содержать повторяющихся значений . Мне нужно было 6 случайных неповторяющихся чисел в диапазоне от 1 до 49. Я начал с создания более длинного набора, состоящего примерно из 30 цифр (если значения повторяются, в наборе будет меньше элементов), я преобразовал набор в массив, а затем разделил его первые 6 элементов. Очень просто. Set.length по умолчанию undefined и бесполезно, поэтому его проще преобразовать в массив, если вам нужна конкретная длина.

let randomSet = new Set();
for (let index = 0; index < 30; index++) {
        randomSet.add(Math.floor(Math.random() * 49) + 1) 
    };
let randomSetToArray = Array.from(randomSet).slice(0,6);
console.log(randomSet);
console.log(randomSetToArray);
0 голосов
/ 29 августа 2013

Вот простое исправление, если немного зачаточное:

if(nextNum == lastNum){
    if (nextNum == 0){nextNum = 7;} 
    else {nextNum = nextNum-1;}
}

Если следующее число совпадает с последним, просто минус 1, если только число не равно 0 (нулю) и установите его на любое другое число в вашем наборе (я выбрал 7, самый высокий индекс).

Я использовал этот метод в функции цикла, потому что единственным условием при выборе числа было то, что оно не должно совпадать с последним.

Не самое элегантное или технически одаренное решение, но оно работает:)

0 голосов
/ 15 июля 2013

не уверен, что уже слишком поздно, но все равно хотел бы добавить -

var RecordKeeper = {};

SRandom = function () {
    currTimeStamp = new Date().getTime();
    if (RecordKeeper.hasOwnProperty(currTimeStamp)) {
        RecordKeeper[currTimeStamp] = RecordKeeper[currTimeStamp] + 1;
        return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
    }
    else {
        RecordKeeper[currTimeStamp] = 1;
        return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
    }
}

это в основном использует метку времени (каждую миллисекунду), чтобы всегда генерировать уникальное число.

0 голосов
/ 08 июля 2011

Обычно мой подход состоит в том, чтобы создать массив, содержащий все возможные значения, и:

  1. Выбрать случайное число <= размер массива </li>
  2. Удалить выбранный элементиз массива
  3. Повторяйте шаги 1-2 до тех пор, пока массив не станет пустым

Полученный набор чисел будет содержать все ваши индексы без повторений.

Еще лучше, может быть, что-то вроде этого:

var numArray = [0,1,2,3,4,5,6];
numArray.shuffle();

Тогда просто пройдите через предметы, потому что случайное перемешивание будет их случайным образом выводить и выталкивать их по одному за раз.

0 голосов
/ 08 июля 2011

не могли бы вы попробовать,

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);
0 голосов
/ 08 июля 2011

вы можете сделать это.Иметь открытый массив ключей, который вы использовали, и проверить их с помощью этой функции:

function in_array(needle, haystack)
{
    for(var key in haystack)
    {
        if(needle === haystack[key])
        {
            return true;
        }
    }

    return false;
}

(функция из: функция javascript inArray )

Итак, что выможно сделать так:

var done = [];
setInterval(function() {
    var m = null;
    while(m == null || in_array(m, done)){
       m = Math.floor(Math.random()*7);
    }
    done.push(m);
    $('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);

Этот код застрянет после получения всех семи чисел, поэтому вам нужно убедиться, что он существует после того, как он их всех закончит.

...