RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 624726
Accepted
Анатолий
Анатолий
Asked:2020-02-08 00:51:45 +0000 UTC2020-02-08 00:51:45 +0000 UTC 2020-02-08 00:51:45 +0000 UTC

从1到1000中获取20个随机数,但要让这些数字不重复

  • 772

如何在 JS 中执行此操作。您需要从到but 中获取20随机数,以便这些随机数不会重复。这个怎么做?所有这些业务都应该循环进行。这是一半代码的示例。11000

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);

    }
javascript
  • 8 8 个回答
  • 10 Views

8 个回答

  • Voted
  1. Best Answer
    Crantisz
    2020-02-08T01:13:09Z2020-02-08T01:13:09Z

    我正在使用Lodash库

    console.log(_.shuffle(_.range(1,1001)).slice(0,20))
    <script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

    没有她:

    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])
    }
    <script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

    • 12
  2. Vladimir Gamalyan
    2020-02-09T15:16:29Z2020-02-09T15:16:29Z

    另一个注意内存和计算资源的选项(尤其是对于大范围的值)。

    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-object m(键是系列中的位置,值是值)。

    • 8
  3. vp_arth
    2020-02-08T15:41:21Z2020-02-08T15:41:21Z

    带有 ES6 的 VanillaJs

    基于算法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)
    }


    说明:

    范围:[...Array(to-from+1).keys()].map(i=>i+from)

    • Array(to-from+1)- 所需长度的数组
    • .keys - 获取索引的 ArrayIterator
    • [...ArrayIterator]- 将其转换为数组
    • .map(i => i + from)- 为每个元素添加一个最小值

    洗牌:.reduce((arr, elt) => (arr.splice(Math.random() * (arr.length + 1), 0, elt), arr), [])

    我们简单地使用来reduce构建一个新数组,在随机位置插入每个新元素


    优化范围

    {
      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]
    }

    • 5
  4. user220409
    2020-02-09T16:05:57Z2020-02-09T16:05:57Z

    关键是在初始阶段我们计算范围,在这个过程中我们减去当前值+以前的值,从而减少形成随机的范围。并且通过将先前的值添加到接收到的值中,我们就不可能重复该数字。

    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 ) ); //

    • 0
  5. SLy_huh
    2020-02-09T16:55:00Z2020-02-09T16:55:00Z

    没有 ES6,香草。老实说,我只是终于找到了用处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);

    • 0
  6. Ваня
    2020-06-07T04:42:30Z2020-06-07T04:42:30Z
    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<i;j++) {
                    if(Array[i] == Array[j]) {
                        i--;
                    }               
                }           
            }
    

    非常抱歉...我的意思是 '\t' 和 '\n' 你可以自己做。

    • 0
  7. ingram 14
    2022-07-16T06:30:07Z2022-07-16T06:30:07Z

    function getRandomNumbersInRange(min, max, count) {
        let result = [];
    
        while (result.length < count) {
            const randomNumber = Math.floor(Math.random() * (max - min)) + min;
            if (result.indexOf(randomNumber) === -1) {
                result.push(randomNumber);
            }
        }
    
        return result;
    }
    
    console.log(getRandomNumbersInRange(1, 1000, 20));

    创建数组并混合它们非常耗费资源。我提供我自己的版本,操作原理非常简单。我们生成一个随机数,如果该数组中还没有这样的数字,则将其放入数组中。然后我们重复此操作,直到数组包含范围内所需数量的随机数。

    优点:

    1. 在给定范围内“诚实”地生成几个随机数。
    2. 它不会创建任何多余的东西,因此它消耗最少的计算机资源(尤其是内存)。

    缺陷:

    1. 每次将新数字添加到数组时,我们都必须检查它的唯一性。(你需要生成的数字越多,它就越昂贵)
    2. 我们不知道究竟会有多少次重复(数字是随机的)。每次重复都是循环的额外迭代。

    实际上,对于 1 到 1000 范围内的 20 个随机数,当运行该函数超过 1,000,000 次时,我得到的“双打”不超过 5 个。

    但是,这不是一个可靠的解决方案!最终要循环多少次是不可能的!因此,下面我将提供一个稍微复杂但可靠的选项。

    function getRandomNumbersInRange(min, max, count) {
        let randomNumbers = [];
    
        while (randomNumbers.length < count) {
            randomNumbers.push(Math.floor(Math.random() * (max - min + 1)) + min);
        }
    
        let uniqueNumbers = new Set();
    
        randomNumbers.forEach(
            n => {
                if (!uniqueNumbers.has(n)) {
                    uniqueNumbers.add(n);
                    return;
                }
    
                let i = 1;
                while (true) {
                    const more = n + i;
                    if (more <= max && !uniqueNumbers.has(more)) {
                        uniqueNumbers.add(more);
                        return;
                    }
    
                    const less = n - i;
                    if (less >= min && !uniqueNumbers.has(less)) {
                        uniqueNumbers.add(less);
                        return;
                    }
    
                    i++;
                }
            }
        );
        
        return [ ...uniqueNumbers ];
    }
    
    console.log(getRandomNumbersInRange(1, 1000, 20));

    在此解决方案中,我们生成给定数量的随机数,然后我们才简单地“唯一”重复项。

    找到一个 double 后,我们正在寻找最近的“未占用”数字,从“double”向上和向下检查一个循环,在每次迭代时加一个。一旦我们找到一个“免费号码”,我们就会用它替换“双”,然后继续寻找“重复”。依此类推,直到所有数字都是唯一的。

    通过这个解决方案,我们可以准确地计算出最坏情况下的迭代次数。很有可能还有更完美的“唯一性”算法,我会继续往这个方向挖掘。

    • 0
  8. Yaant
    2022-07-16T16:33:56Z2022-07-16T16:33:56Z

    纯粹为了收藏,使用Set.

    function rndNumbers(min, max, count) {
      if (count > max - min + 1) throw "impossible";
      let set = new Set();
      while (set.size < count) {
        let num = (Math.random() * (max - min + 1) + min) | 0;
        set.add(num);
      }
      return [...set];
    }
    
    console.log(rndNumbers(1, 1000, 10));
    console.log(rndNumbers(10, 20, 11));
    console.log(rndNumbers(100, 200, 1000));

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5