【问题标题】:Pick always a different number in a range of 3K numbers总是在 3K 个号码的范围内选择一个不同的号码
【发布时间】:2014-11-26 19:06:19
【问题描述】:

我正在用 Javascript 构建一个混合应用程序,它随便从数据库中选择一个练习,等待用户解决它,然后再选择另一个练习。

在这一点上没什么难的,我的问题是总是从数据库中选择不同的练习。

现在我的代码以这种方式“工作”:

  1. 获取练习总数(约 3K),
  2. 生成一个从1到3000的N个随机数,
  3. 从 DB 中选择 N 练习,
  4. 将 N 号保存在 'used' db 表中,
  5. 生成另一个号码名称,
  6. 这次首先检查生成的号码是否已经被使用过,
  7. 如果 NO 选择练习,如果 YES 生成另一个号码,
  8. 等等……

代码对前 2000-2500 个数字运行良好,然后开始变得非常慢,因为生成一个尚未使用的随机数开始变得非常困难。当使用的数字略小于 3K 时,代码完全损坏:继续检查,但新数字永远不会出现

我怎样才能以尽可能少的内存使用的快速和轻松的方式处理这种情况?

非常感谢!

编辑

我在 phonegap 应用程序中使用 WebSQL

这就是我正在做的(代码):

这里我得到了练习的数量

1. SELECT COUNT(*) AS countArt FROM Exercises'

这里我选择一个从 1 到 totalNumberOfExercises 的随机数

2. randomNumber = random(totalNumberOfExercises);
   function numeroCasuale(len){
        var num = Math.floor(Math.random() * len) + 0;
        return num;
    };

这里我检查我的 randomNumber 是否已经在数据库中,这意味着已经使用了

4. SELECT EXISTS(SELECT * FROM alreadyUsed WHERE numero=randomNumber)

如果 randomNumber 存在,我会生成另一个 randomNumber 并一次又一次地检查它......

【问题讨论】:

  • 最好从所有可能的 3000 个数字中生成一个数组,然后删除已经使用的数字,然后从剩余未使用的数字中获取一个随机数
  • 将 1 到 3000 的数字放入一个数组中,然后打乱数组。然后,您可以通过增加数组的索引来选择数字,并且保证不会重复。
  • 如何生成这个随机数(SQL 或应用程序)?你用的是什么数据库?可以发一些代码吗?
  • @Pointy 你如何洗牌?
  • 生成一个介于 1 到 3000 之间的随机数。如果该数字已生成 not been previously,则标记该数字已使用。如果数字是 used previously,请使用 next 数字,即(随机数 + 1)。如果它是索引中的最后一个数字,则转到第一个数字。通过这种方式,您将始终获得unused 号码。为了加速这个过程,您可以预先计算随机数并存储在表中,然后简单地一个接一个地获取表中的下一个索引。

标签: javascript arrays database random


【解决方案1】:

使用来自另一个 stackoverflow question 的这个 shuffle 函数:

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

你可以创建这个:

function generateRandomSequence(amount){
    var random = [];
    for (var i = 0; i<amount; i++) random[i] = i;
    return shuffle(random);
}

var random = generateRandomSequence(3000);
var gamesCompleted = 0;

function nextGame(){
    console.log(random[gamesCompleted]);
    gamesCompleted++;
}

nextGame();

这将创建一个数组,其中位置 0 = 0、1 = 1 等等,并将其打乱,因此我们有一个没有重复的随机序列。跟踪您完成了多少游戏,并将此数字用作下一个问题的索引。 Here's a fiddle.

【讨论】:

  • 我认为您的回答很好,但我的问题是我需要永久存储随机数数组,因为代码需要在 peonegap 应用程序中运行,我希望选择的练习是唯一的如果用户关闭应用程序
  • 啊哈。那么在这种情况下,将其保存在本地存储中。快速示例,当应用程序启动时检查 localStorage.getItem('randomSequence') == null 是否为 true,生成序列并将其保存到 localStorage,如果为 false,则从那里获取项目。您需要使用JSON.stringify()JSON.parse() 将其作为字符串存储在localStorage 中。不要忘记保存和加载游戏完成的数量。那有意义吗?如果您愿意,我可以写一个示例并将其添加到答案中。
  • 非常感谢!我知道localStorage,我只是一个问题:localStorage 读/写不是很“慢”吗?
  • 如果你有很多数据,也可以是同步的,这意味着你的应用程序在数据加载时会挂起。我认为您应该对其进行测试以查看影响。将日期对象保存到变量中,并在加载和保存后从另一个日期对象中减去它。最重要的是,您将在每个安装生命周期编写一次序列,并在每次用户打开应用程序时检索它(而不是从后台)。在我看来这还不错。
  • 如何使用 WebSQL(我已经在使用)?应该更快,还是我错了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-17
相关资源
最近更新 更多