javascript array no repeat [duplicate]

неопределенная ссылка на WinMain@16 или аналогичную «необычную» main() ссылку на точку входа (особенно для ).

Вы возможно, пропустили, чтобы выбрать правильный тип проекта с вашей реальной IDE. IDE может захотеть связать, например. Проекты приложений Windows для такой функции точки входа (как указано в недостающей ссылке выше) вместо обычной int main(int argc, char** argv);.

Если ваша среда IDE поддерживает Plain Console Projects , вы может захотеть выбрать этот тип проекта вместо проекта приложения Windows.


Здесь case1 и case2 обрабатываются более подробно из реальный мир проблема.

8
задан BYossarian 14 September 2013 в 22:39
поделиться

7 ответов

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

Это вычислит случайную перестановку чисел в nums:

var nums = [1,2,3,4,5,6,7,8,9,10],
    ranNums = [],
    i = nums.length,
    j = 0;

while (i--) {
    j = Math.floor(Math.random() * (i+1));
    ranNums.push(nums[j]);
    nums.splice(j,1);
}

Итак, например, если вы искали случайные числа между 1-20, которые были даже четными, то вы могли бы использовать:

nums = [2,4,6,8,10,12,14,16,18,20];

Затем просто прочитайте ranNums в чтобы запомнить случайные числа.

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

EDIT: после чтения это и выполнение теста на jsperf , кажется, что гораздо лучший способ сделать это - переключение Fisher-Yates:

function shuffle(array) {
    var i = array.length,
        j = 0,
        temp;

    while (i--) {

        j = Math.floor(Math.random() * (i+1));

        // swap randomly chosen element with current element
        temp = array[i];
        array[i] = array[j];
        array[j] = temp;

    }

    return array;
}

var ranNums = shuffle([1,2,3,4,5,6,7,8,9,10]);

В принципе, это больше эффективными, избегая использования «дорогих» операций с массивами.

BONUS EDIT: Другая возможность - использование генераторов (если у вас есть поддержка ):

function* shuffle(array) {

    var i = array.length;

    while (i--) {
        yield array.splice(Math.floor(Math.random() * (i+1)), 1)[0];
    }

}

Затем, чтобы использовать:

var ranNums = shuffle([1,2,3,4,5,6,7,8,9,10]);

ranNums.next().value;    // first random number from array
ranNums.next().value;    // second random number from array
ranNums.next().value;    // etc.

, где ranNums.next().value в конечном итоге будет оценивать undefined после того, как вы запустите thr все элементы в перетасованном массиве.

В целом это будет не так эффективно, как Fisher-Yates Shuffle, потому что вы все еще splice - массив. Но разница в том, что вы сейчас делаете эту работу только тогда, когда вам это нужно, а не делаете все это заранее, поэтому в зависимости от вашего варианта использования это может быть лучше.

17
ответ дан BYossarian 1 September 2018 в 03:23
поделиться

Вот как я это достигаю, используя underscore.js

Чтобы получить n целые числа от значений min до max. Где n - аргумент size.

var randomNonRepeatingIntFromInterval = function(min, max, size) {
    var values = [];

    while (values.length < size) {
      values.push(Math.floor(Math.random() * ( max - min + 1) + min));

      values = _.uniq(values);
    }

    return values;
  }
0
ответ дан Carlo Rodríguez 1 September 2018 в 03:23
поделиться
<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Math.random()</h2>

<p>Math.random() returns a random number between 0 (included) and 1 (excluded):</p>

<p id="demo"></p>

<script>


var storeArray = []

function callRamdom(){
    var randomNumber = Math.floor(Math.random() * 5);   
    return randomNumber;
}

function randomStore(){ 

    var localValue = callRamdom()
    var status = false;
    for(i=0;i<5; i++){
    var aa = storeArray[i];
        if(aa!=localValue){
            console.log(storeArray[i]+"hhhhh"+ localValue); 
            if(i==4){
                status=true;        
            }

        }   
        else
        break;

    }

    if(status==true){

        storeArray.push(localValue);    
    }
    if(storeArray.length!=5){
        randomStore();
    }   

    return storeArray;
}



document.getElementById("demo").innerHTML = randomStore();


</script>

</body>
</html>
0
ответ дан Mayank Sudden 1 September 2018 в 03:23
поделиться

Вы действительно не хотите потерять случайные числа. Поистине случайные числа должны быть в состоянии повторить.

Действительно, случайное число похоже на бросание кубиков. Любое число может появиться дальше.

Перемешанные числа похожи на рисование игральных карт. Каждый номер может появиться только один раз.

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

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

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

-1
ответ дан midimagic 1 September 2018 в 03:23
поделиться
function randomNumbers(max) {
    function range(upTo) {
        var result = [];
        for(var i = 0; i < upTo; i++) result.push(i);
        return result;
    }
    function shuffle(o){
        for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
        return o;
    }
    var myArr = shuffle(range(max));
    return function() {
        return myArr.shift();
    };
}

Построен небольшой тест, попробуйте это на jsfiddle :

var randoms = randomNumbers(10),
    rand = randoms(),
    result = [];
while(rand != null) {
    result.push(rand);
    rand = randoms();
}
console.log(result);

Функция случайного воспроизведения предоставлена ​​ dzone.com .

0
ответ дан Niccolò Campolungo 1 September 2018 в 03:23
поделиться

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

Где _a - это коллекция, а r не является частью коллекции, мы получаем случайное значение r:

function aRandom(f){
  var r = Math.random();
  aRandom._a[r] ? aRandom(f) : f(r,aRandom._a[r] = 1);
}
aRandom._a = {};

//usage:
aRandom(function(r){ console.log(r) });

Redefine aRandom._a когда браузер становится вялым. Чтобы избежать возможной медлительности, нужно действительно использовать алгоритм генерации UUID с достаточной энтропией, чтобы шансы на повторение были фактически нулевыми, а не грубыми, вытесняющими дифференцируемость. Я выбрал имя функции aRandom, потому что латинский префикс A означает «отсюда». Так как чем больше он используется, тем дальше от случайного выхода. Функция генерирует миллион уникальных значений в 2100 мс на Macbook.

Преимущество вышеупомянутого решения не нужно ограничивать набор. Кроме того, несколько абонентов могут использовать его одновременно и предположить, что их значения отличаются от всех других абонентов. Это удобно для таких вещей, как шумоподавляющие распределения с застрахованным без перекрытий.

Однако его можно модифицировать так, чтобы возвращать целые числа, чтобы ограничить использование плунжера до указанной длины:

function aRandom(f,c){
  var r = Math.floor(Math.random()*c);
  aRandom._a[r] ? aRandom(f,c) : f(r,aRandom._a[r] = 1);
}
aRandom._a = {};


//usage:
var len = 10;
var resultset = [];
for(var i =0; i< len; i++){
  aRandom(function(r){ resultset.push(r); }, len);
}
console.log(resultset);
0
ответ дан Radio 1 September 2018 в 03:23
поделиться

Проблема заключается в том, что по мере приближения к насыщению вы начинаете получать больше и больше, чтобы генерировать уникальный номер «случайно». Например, в приведенном выше примере max равен 10. После того, как использованный массив чисел содержит 8 чисел, потенциально может потребоваться много времени для поиска 9-го и 10-го. Вероятно, здесь создается максимальная ошибка стека вызовов.

jsFiddle Demo showing iteration count being maxed

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

jsFiddle Demo with early break

if( used.length >= max ) return undefined;

И последний способ выполнить оба итерационные проверки и бесконечная рекурсия будут такими, как jsFiddle Demo :

function randomNum(max, used, calls){
 if( calls == void 0 ) calls = 0;
 if( calls++ > 10000 ) return undefined;
 if( used.length >= max ) return undefined;
 var newNum = Math.floor(Math.random() * max + 1);
 if($.inArray(newNum, used) === -1){
   return newNum;
 }else{
   return randomNum(max,used,calls);
 }
}
1
ответ дан Travis J 1 September 2018 в 03:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: