Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

产生一个不重复的随机数组 #140

Open
Sunny-117 opened this issue Nov 3, 2022 · 15 comments
Open

产生一个不重复的随机数组 #140

Sunny-117 opened this issue Nov 3, 2022 · 15 comments

Comments

@Sunny-117
Copy link
Owner

No description provided.

@zhuba-Ahhh
Copy link
Contributor

// 参数 数组长度、最小范围、最大范围
function randomUniqueArr(len = 100, min = 0, max = 200) {
  if (max - min < len) {
    // 可生成数的范围小于数组长度
    return null;
  }
  const hash = [];
  while (hash.length < len) {
    const num = Math.floor(Math.random() * max);
    if (num < min) continue;
    if (hash.indexOf(num) === -1) {
      hash.push(num);
    }
  }
  return hash;
}

console.log(randomUniqueArr());
console.log(randomUniqueArr(20, 10, 31));

image

@fencer-yd
Copy link

fencer-yd commented Jan 11, 2023

function randomUniqueArr(len, min, max) {
  if (!len || len <= 0) return []
  const _min = Math.min(min, max);
  const _max = Math.max(min, max);
  if (!(_max - _min)) return [_max];
  if (len >= _max - _min) return new Array(_max - _min + 1).fill(null).map((_, idx) => idx + _min);
  const set = new Set();
  while (set.size < len) {
    set.add(~~(Math.random() * _max) + _min);
  }
  return [...set];
}

const a = randomUniqueArr(100, 10000, 100000000);
const b = randomUniqueArr(100, 1, 50);
const c = randomUniqueArr()
const d = randomUniqueArr(100, 100, 100)
console.log(a, a.length);
console.log(b, b.length);
console.log(c, c.length);
console.log(d, d.length);

@bearki99
Copy link

// 1. 简单版数组乱序
function generateRandomV1(num) {
  return num.sort(() => Math.random() - 0.5);
}
// 2. 复杂版
function generateRandom(len = 10, min = 1, max = 30) {
  if (max - min < len) return null;
  const hash = [];
  while (hash.length < len) {
    const num = Math.floor(Math.random() * max);
    if (num < min) continue;
    if (hash.indexOf(num) === -1) hash.push(num);
  }
  return hash;
}
const res = generateRandom();
console.log(res);

@vivipure
Copy link

function randomUniqueArr(len: number, min: number, max: number) {
  if (max - min + 1 < len) {
    return null;
  }
  const hash: number[] = [];
  while (hash.length < len) {
    const num = Math.round(Math.random() * (max - min)) + min;
    if (!hash.includes(num)) {
      hash.push(num);
    }
  }
  return hash;
}

注意点:

  1. 判断是否包含数量应该是 max - min + 1 < num, 比如 1 和 2 之间是可以选中两个的
  2. 取值用 Math.round 保证可以取到最大值和最小值

@crazy23lt
Copy link

function fn(max, min, len, set = new Set()) {
	if (max - min < len) throw new Error("len 超过了取值范围");
	while (set.size < len) {
		set.add(Math.ceil(Math.random() * (max - min) + min));
	}
	return [...set];
}
function curry(fn) {
	const target = arguments[0];
	let args = Array.prototype.slice.call(arguments, 1);
	return function () {
		args.push(...arguments);
		if (args.length < fn.length) {
			return arguments.callee;
		} else {
			return target(...args);
		}
	};
}
let fnn = curry(fn, 10, 5);
let fnnn = curry(fn, 20, 15);
let fnnnn = curry(fn, 30, 25);
let fnnnnn = curry(fn, 40, 5);
console.dir(fnn(5));
console.dir(fnnn(5));
console.dir(fnnnn(5));
console.dir(fnnnnn(35));

@MoYuanJun
Copy link

const randomUniqueArr = (len, min, max) => {
    // min、max 是可以获取到的
    if (max - min < len - 2) {
      return []
    }

    const set = new Set()    
    while (set.size < len) {
      // 取值用 Math.round 保证可以取到最大值和最小值
      const num = Math.round(Math.random() * (max - min)) + min;
      set.add(num)
    }

    return [...set]
}


const res = randomUniqueArr(2, 2, 3)

@fangbw17
Copy link

fangbw17 commented Mar 16, 2023

function random(len = 10, min = 0, max = 200) {
    if (max < min) {
        throw new Error("max must greater hhan or equalTo min!");
    }
    if (max - min + 1 < len) {
        throw new Error(
            "len must greater hhan or equalTo the sum of min and max !"
        );
    }

    const numbers = new Set();
    while (len !== numbers.size) {
        const num = Math.floor(Math.random() * (max - min) + min);
        numbers.add(num);
    }

    return [...numbers];
}

@morp-hex
Copy link

morp-hex commented Apr 6, 2023

        //返回一个两数之间的随机整数[min max]
        function getRandomIntInclusive(min, max) {
            var _min = Math.ceil(Math.min(min, max));
            var _max = Math.floor(Math.max(min, max));
            return Math.floor((Math.random() * (_max - _min + 1) + _min));
        }

        //返回目标数组 len 数组长度 min max 随机数区间
        function randomUniqueArr(len, min, max) {
            //防止数组长度大于随机区间
            if (len > Math.abs(max - min + 1))
                return '数组长度大于随机区间,无法产生一个不重复的随机数组';
            var arr = [];
            while (arr.length < len) {
                var ran = getRandomIntInclusive(min, max);
                if (arr.indexOf(ran) == -1)
                    // arr[arr.length] = ren;
                    arr.push(ran);
            }
            return arr;
        }
        var arr1 = randomUniqueArr(20, 20, 50);
        var arr2 = randomUniqueArr(20, 21, 40);
        var arr3 = randomUniqueArr(20, 20, 30);
        console.log(arr1);
        console.log(arr2);
        console.log(arr2.sort());
        console.log(arr3);
        //注意Math.random()的随机区间[0 1)
       //输入的数据 数组长度不能大于随机区间

@JeromeD3
Copy link

JeromeD3 commented Apr 8, 2023

function randomUniqueArr(len, min = 0, max = 10) {
let arr = []
while (arr.length < len) {
let num = Math.floor(Math.random() * (max - min + 1) + min)
if (arr.indexOf(num) === -1) {
arr.push(num)
}
}
return arr
}

@huccct
Copy link

huccct commented May 11, 2023

时间复杂度为 O(n)

经典算法 Fisher-Yates

function generateRandomArray(length) {
  let arr = [];
  for (let i = 1; i <= length; i++) {
    arr.push(i);
  }
  // Fisher-Yates算法
  for (let i = arr.length - 1; i > 0; i--) {
    const randomIndex = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
  }
  return arr;
}

const arr = generateRandomArray(10);
console.log(arr);

@printfCYQ
Copy link

时间复杂度为 O(n) 经典算法 Fisher-Yates

function generateRandomArray(length) {
  let arr = [];
  for (let i = 1; i <= length; i++) {
    arr.push(i);
  }
  // Fisher-Yates算法
  for (let i = arr.length - 1; i > 0; i--) {
    const randomIndex = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
  }
  return arr;
}

const arr = generateRandomArray(10);
console.log(arr);
function generateRandomArray(len, min, max) {
  const range = Array.from({length: max - min + 1}, (_, index) => index + min);
  for (let i = range.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [range[i], range[j]] = [range[j], range[i]];
  }
  const result = range.slice(0, len);
  return result;
}

const len = 100;
const min = 0;
const max = 200;

const randomArray = generateRandomArray(len, min, max);
console.log(randomArray);

@mafeiGitHub
Copy link

mafeiGitHub commented Oct 12, 2023

// 参数 数组长度、最小范围、最大范围
function randomUniqueArr(len, max, min) {
    if (max - min < len) return [];
    const result = [];
    while (result.length < len) {
        let num = Math.round(Math.random() * (max - min) + min);
        if (!result.includes(num)) {
            result.push(num);
        }
    }
    return result;
}

@captain-kuan
Copy link

function randomUniqueArr(len: number, min: number, max: number): number[] {
  if (max - min < len) throw Error("out of bounds");
  return Array(max + 1 - min)
    .fill(max)
    .map((max, i) => max - i)
    .sort(() => Math.random() - 0.5)
    .slice(0, len);
}

@csdoge007
Copy link

function randomUniqueArr(len, min, max) {
  if (!len || len <= 0) return [];
  const _min = Math.min(min, max);
  const _max = Math.max(min, max);

  // 特殊情况处理
  if (_max - _min + 1 < len) {
    throw new Error("Range is too small to generate the required number of unique elements");
  }

  // 生成从 _min 到 _max 的所有整数数组
  const rangeArray = new Array(_max - _min + 1).fill(null).map((_, idx) => idx + _min);

  // Fisher-Yates 洗牌算法
  for (let i = rangeArray.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [rangeArray[i], rangeArray[j]] = [rangeArray[j], rangeArray[i]];
  }

  // 返回前 len 个元素
  return rangeArray.slice(0, len);
}

@Windseek
Copy link

const randomUniqueArr = (len, max, min) => {
  if((max - min) < len - 1) {
    return [];
  }
  const set = new Set();
  while (set.size < len) {
    set.add(Math.round(Math.random() * (max - min)) + min);
    console.log(...set);
  }
  return [...set];
};

console.log(randomUniqueArr(2, 4, 3));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests