J'ai besoin de générer un ensemble d'entiers uniques (pas de doublons), et entre 0 et un nombre donné.
C'est:
var limit = 10;
var amount = 3;
Comment puis-je utiliser Javascript pour générer 3 nombres uniques entre 1 et 10?
Utilisez les méthodes de base Math
:
Math.random()
renvoie un nombre aléatoire compris entre 0 et 1 (y compris 0, à l'exclusion de 1).Autour de ce nombre
Math.floor(Math.random()*10) + 1
Exemple:
//Example, including customisable intervals [lower_bound, upper_bound)
var limit = 10,
amount = 3,
lower_bound = 1,
upper_bound = 10,
unique_random_numbers = [];
if (amount > limit) limit = amount; //Infinite loop if you want more unique
//Natural numbers than exist in a
// given range
while (unique_random_numbers.length < limit) {
var random_number = Math.floor(Math.random()*(upper_bound - lower_bound) + lower_bound);
if (unique_random_numbers.indexOf(random_number) == -1) {
// Yay! new random number
unique_random_numbers.Push( random_number );
}
}
// unique_random_numbers is an array containing 3 unique numbers in the given range
Math.floor(Math.random() * (limit+1))
Math.random()
génère un nombre à virgule flottante compris entre 0 et 1, Math.floor()
l'arrondit à un entier.
En le multipliant par un nombre, vous créez effectivement la plage 0..number-1
. Si vous souhaitez le générer dans une plage de num1
À num2
, Faites:
Math.floor(Math.random() * (num2-num1 + 1) + num1)
Pour générer plus de nombres, utilisez simplement une boucle for et placez les résultats dans un tableau ou écrivez-les directement dans le document.
function generateRange(pCount, pMin, pMax) {
min = pMin < pMax ? pMin : pMax;
max = pMax > pMin ? pMax : pMin;
var resultArr = [], randNumber;
while ( pCount > 0) {
randNumber = Math.round(min + Math.random() * (max - min));
if (resultArr.indexOf(randNumber) == -1) {
resultArr.Push(randNumber);
pCount--;
}
}
return resultArr;
}
Selon la plage nécessaire, la méthode de retour de l'entier peut être modifiée en: ceil (a, b], round [a, b], floor = [a, b), car (a, b) consiste à ajouter 1 à min avec plancher.
Math.floor(Math.random()*limit)+1
for(i = 0;i <amount; i++)
{
var randomnumber=Math.floor(Math.random()*limit)+1
document.write(randomnumber)
}
Voici un autre algorithme pour garantir que les nombres sont uniques:
Par rapport à la méthode de génération de nombres aléatoires jusqu'à ce que vous en obteniez un unique, cette méthode utilise plus de mémoire, mais elle a un temps d'exécution plus stable - les résultats sont garantis d'être trouvés en temps fini. Cette méthode fonctionne mieux si la limite supérieure est relativement basse ou si la quantité à prendre est relativement élevée.
Ma réponse utilise la bibliothèque Lodash pour plus de simplicité, mais vous pouvez également implémenter l'algorithme décrit ci-dessus sans cette bibliothèque.
// assuming _ is the Lodash library
// generates `amount` numbers from 0 to `upperLimit` inclusive
function uniqueRandomInts(upperLimit, amount) {
var possibleNumbers = _.range(upperLimit + 1);
var shuffled = _.shuffle(possibleNumbers);
return shuffled.slice(0, amount);
}
Quelque chose comme ça
var limit = 10;
var amount = 3;
var nums = new Array();
for(int i = 0; i < amount; i++)
{
var add = true;
var n = Math.round(Math.random()*limit + 1;
for(int j = 0; j < limit.length; j++)
{
if(nums[j] == n)
{
add = false;
}
}
if(add)
{
nums.Push(n)
}
else
{
i--;
}
}
Comme indiqué, la réponse acceptée est fausse. Voici un générateur de nombres de puces non répétitif avec pratiquement aucun impact sur la mémoire et aucun problème de O(n)) qui est bon pour 10 000 000 de numéros.
Voici un plunkr démontrant le port javascript ci-dessous du générateur aléatoire non répétitif trouvé ici github.com/preshing/RandomSequence .
var RandomSequenceOfUnique = (function() {
function RandomSequenceOfUnique(seedBase, seedOffset) {
var prime = 4294967291,
residue,
permuteQPR = function(x) {
if (x >= prime)
return x;
residue = (x * x) % prime;
return (x <= prime / 2) ? residue : prime - residue;
}
this.next = function() {
return permuteQPR((permuteQPR(this.index++) + this.intermediateOffset) ^ 0x5bf03635);
}
this.index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
this.intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905);
}
return RandomSequenceOfUnique;
}());
Construisez une instance et générez un nombre:
var generator = new RandomSequenceOfUnique(Date.now(), parseInt(Math.random() * 10000));
Utilisation du générateur:
var num = generator.next();
Voici un article expliquant les mathématiques derrière le générateur, Comment générer une séquence d'entiers aléatoires uniques
var randomNums = function(amount, limit) {
var result = [],
memo = {};
while(result.length < amount) {
var num = Math.floor((Math.random() * limit) + 1);
if(!memo[num]) { memo[num] = num; result.Push(num); };
}
return result; }
Cela semble fonctionner, et sa recherche constante de doublons.
/**
* Generates an array with numbers between
* min and max randomly positioned.
*/
function genArr(min, max, numOfSwaps){
var size = (max-min) + 1;
numOfSwaps = numOfSwaps || size;
var arr = Array.apply(null, Array(size));
for(var i = 0, j = min; i < size & j <= max; i++, j++) {
arr[i] = j;
}
for(var i = 0; i < numOfSwaps; i++) {
var idx1 = Math.round(Math.random() * (size - 1));
var idx2 = Math.round(Math.random() * (size - 1));
var temp = arr[idx1];
arr[idx1] = arr[idx2];
arr[idx2] = temp;
}
return arr;
}
/* generating the array and using it to get 3 uniques numbers */
var arr = genArr(1, 10);
for(var i = 0; i < 3; i++) {
console.log(arr.pop());
}