Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Получить 20 случайных чисел от 1 до 1000, но чтобы эти числа не повторялись

#javascript


Как на JS сделать такую задачу. Нужно получить 20 случайных чисел от 1 до 1000 но
чтобы эти случайные числа не повторялись. Как сделать такое? 
Все это дело должно работать в цикле.
Вот пример половины кода.

var random_start = 1; // От какого генерировать
var random_end = 1000; // До какого генерировать

    allСycles = 20;
    for(countCycles=1;countCycles<=allСycles;countCycles++){
    alert ("Случайное рандомное и уникально не повторающиеся число от 1 до 1000");
    }


Пробовал по подсказкам так, но бывает числа повторяются

var random_end = 1000;
allСycles = 20;
    for(countCycles=1;countCycles<=allСycles;countCycles++){

        var test = Math.floor(Math.random()*(random_end+1)+1);
        alert(test);

    }

    


Ответы

Ответ 1



Использую библиотеку Lodash console.log(_.shuffle(_.range(1,1001)).slice(0,20)) Без нее: var random_start = 1; // От какого генерировать var random_end = 1000; // До какого генерировать allСycles = 20; var array= [] for(i=random_start;i<=random_end;i++){ array.push(i) } for(countCycles=1;countCycles<=allСycles;countCycles++){ console.log(array.splice(Math.random()*array.length,1)[0]) }

Ответ 2



Ещё один вариант, бережный к памяти и вычислительным ресурсам (особенно для больших диапазонов значений). const range = 1000000; // максимальное значение (1..1000000 включительно) const count = 10; // кол-во требуемых чисел let m = {}; let a = []; for (let i = 0; i < count; ++i) { let r = Math.floor(Math.random() * (range - i)); a.push(((r in m) ? m[r] : r) + 1); let l = range - i - 1; m[r] = (l in m) ? m[l] : l; } console.log(a); Не требует предварительного создания и заполнения большого массива, кол-во итераций цикла соответствует кол-ву генерируемых чисел (нет перебора значений при коллизиях). Как это работает? Допустим нам нужно выбрать три числа из ряда 0..9 включительно: Выбираем случайный индекс от 0 до 9, к примеру выпадает 3: Теперь, чтобы число 3 больше не попадалось, считаем его использованным, и переносим на его место последний элемент из ряда (9): Теперь у нас девять элементов, среди которых опять выбираем случайный, ставим на его место последний и т.д. Т.к. требуемых на выходе чисел относительно немного, то запоминаем только перестановки (для остальных элементов, значение просто равно их индексу). Для этого используется js-объект m (ключами являются позиции в ряде, а значениями - значения).

Ответ 3



VanillaJs с ES6 На основе алгоритма range/shuffle/slice не подходит для очень больших диапазонов значений { let from=1, to=1000, n = 10; let result = [...Array(to-from+1).keys()].map(i=>i+from) // range .reduce((arr, elt) => (arr.splice(Math.random() * (arr.length + 1), 0, elt), arr), []) // shuffle .slice(0, n); // slice n console.log(result) } Пояснения: range: [...Array(to-from+1).keys()].map(i=>i+from) Array(to-from+1) - массив необходимой длинны .keys - получаем ArrayIterator индексов [...ArrayIterator] - конвертируем его в массив .map(i => i + from) - добавляем каждому элементу минимальное значение shuffle: .reduce((arr, elt) => (arr.splice(Math.random() * (arr.length + 1), 0, elt), arr), []) Просто с помощью reduce строим новый массив, вставляя каждый новый элемент в случайную позицию Оптимизированный range { class Range { constructor(start, end) { this.start = start; this.end = end; } includes(num) { return this.start <= num && num < this.end; } [Symbol.iterator]() { // Для for (el of range); let i = this.start; return { next: () => ({ value: i, done: ++i > this.end }) }; } length() { return this.end - this.start; } sample(count) { if (count > this.length()) { throw new Error('Не хватает элементов'); } let selected = {}; for (let i = 0; i < count; i++) { let num; do { num = Math.floor(Math.random() * this.length()) + this.start; } while (num in selected); selected[num] = 1; } return Object.keys(selected).map(Number); } } let r = new Range(1e9, 1e10); console.log(r.includes(1e9 + 50)); console.log(r.includes(1e9 - 50)); for (let i of new Range(5, 8)) console.log(i); console.log(r.sample(3)); console.log((new Range(1, 5)).sample(4)); // always all [1,2,3,4] }

Ответ 4



Смысл в том, что мы на начальном этапе рассчитываем диапазон от которого в процессе отнимаем текущее значение + предыдущие, тем самым уменьшая диапазон из которого будет формироваться рандом. А прибавляя к полученному значению предыдущие значение мы делаем невозможность повторения числа. const generateRangeRandomArray = (start, end, length) => { let result = []; let ratio = Math.round( (end - start) / length ); let current = NaN; let prev = 0; for(let i = 0; i < length; i++){ current = Math.round( Math.random() * (ratio + ( ratio * i - prev ) ) ); prev += current; result.push( prev ); } return result; } console.log( generateRangeRandomArray( 1, 1000, 10 ) ); //

Ответ 5



Без ES6, vanilla. Честно говоря, просто наконец нашел применение do... while, хоть в календаре день отмечай. var i = 0, arr = [], count = 20, diff, curr, limits = [0,1000]; diff = limits[1] - limits[0]; while( i++ < count && (diff >= (count - 1))){// В случае, если количество чисел на выходе превышает максимальное количество уникальных do{ curr = Math.floor(Math.random() * (diff + 1) + limits[0]); } while ((arr.indexOf(curr) != -1)); arr.push(curr); } console.log(arr);

Ответ 6



int [] Array = new int[20]; for(int i = 0; i < Array.length;i++) { if(i ==0) { Array[i] = (int)(Math.random()*1000+1); continue;} else if(i != 0) { Array[i] = (int)(Math.random()*1000+1); } for(int j = 0; j

Комментариев нет:

Отправить комментарий