【问题标题】:Comparing numbers or using prime numbers?比较数字还是使用素数?
【发布时间】:2011-05-04 13:07:10
【问题描述】:

我正在编写一个生成宾果卡号的程序。宾果卡由 5 列组成,每列 4 个数字。第一列只能包含数字 1-8,第二列只能包含数字 9-16,依此类推(最多 40 个)。

所以在数据库中,我所做的是为此我有两个表。第一个表用于列号。每列包含一组唯一的数字(每列 70 组,即 8 取 4 的组合)。对于 5 列,我将有 350 套。第二张表是卡号。这由 5 列组成,每列对应 B、I、N、G、O 的行。总共有 1,680,700,000。此表的可能组合。我这样做是因为每个游戏的每张卡片都是重复的,只有卡片的控制编号是唯一的。

我想跟踪每个开奖号码的中奖卡。我需要尽可能快地进行跟踪,因为这里谈论的是数百万张卡片。我想到了 2 个选项:

首先,检查每个抽出的号码是否存在于卡片上,从而最小化每次抽出的牌池。

其次,为每个数字(1-40)关联一个唯一的素数,将它们相乘并将乘积与列相关联(我称之为素数索引)。每列的 5 个素数索引相乘,乘积与每个卡片/组合(我称之为卡片索引)相关联。当一个数字被抽出时,相关的素数会从卡片索引中分离出来,检查抽出的数字是否是卡片索引的一个因素。每次连续抽奖都会减少卡片索引(对于池中的每张卡片),因此如果存在获胜卡片,则减少为 1。我将使用 MySQL 和 Java。这两种技术中哪一种是更快的方法?我也会考虑内存空间、负载等,但对我来说更重要的是跟踪的速度。非常感谢!

附:抱歉,解释太长了。我只是想澄清一些事情。 :D

【问题讨论】:

    标签: java mysql performance combinations


    【解决方案1】:

    如果您想真正快速,只需在需要时将 2400 万张卡保存在内存中,然后进行简单的比较即可。为此使用数据库是矫枉过正的,只会让一切变得更加困难。 RAM 不再昂贵。

    【讨论】:

    • 如果没有数据库,我无法做到这一点,因为我还跟踪卡的所有者和购买地点?正如我之前提到的,每场比赛都会重复卡片。
    • +1 这当然是一种方法。即使有 2400 万张卡,包含 40 个 64 位数字(如果您将卡号存储在一个大的 64 位数字中,这本身就是多余的),您仍然只看到 40*8 = 320 MB 的 RAM存储整套可能的卡片。
    • 就卡的所有者而言,您仍然可以在内存中执行此操作。我的意思是,从某种意义上说,数据库只是一种存储大量数据的方法,而这些数据本来是无法存储在 RAM 中的。如果您出于某种原因需要将卡片存储在数据库中,您可以随时在应用程序关闭时保存它们。 320MB 的 RAM,除非您使用的是 RAM 限制非常严格的嵌入式系统,否则基本上是非常小的 RAM。
    • 实际上是十亿张卡片组合。还有可能吗?
    • 您可以将所有者ID保存在内存中,并根据内存中确定的结果更新/查找数据库。
    【解决方案2】:

    正好有 70^5=1,680,700,000 张可能的牌。无需存储卡本身。您可以直接计算卡上的数字,只需索引。反过来,给定数字,找到卡片的索引,只是有点困难。

    例如,卡片 #1421934546。把它放在基数 70 中得到:59 15 40 50 46。 (我的意思是46 + 70*50 + 70^2*40 + 70^3*15 + 70^4*59 = 1421934546)。因此,第一列是可能的 70 次拍摄中的第 46 次(实际上是第 47 次,因为一次次拍摄)。

    根据抽出的数字,您可以快速找到匹配的列。例如,数字 1,2 和 3。第一列中有 5 个匹配的集合,12341235123612371238。因此,所有匹配的卡片都有 % 70 这 5 个 ID 之一。如果您找到每列的所有可能集合,笛卡尔积将给出所有匹配的卡片。

    【讨论】:

    • 我将使用素数。我认为这比使用加法和乘法以 70 为底要快得多
    • @Jairo - 嗯。我的做法真的很不一样。我的意思是,您不需要搜索获胜的卡片,您只需计算它。即使使用加法和乘法也更快。
    【解决方案3】:

    您不必像在卡上一样排列内存中的数据。例如如果您有 N 个可以选择或不选择的方格,那么 BitSet 可能是一个不错的选择。这使用每平方 1 位(有一些开销)。

    假设您最多有 64 个方格,这是一个长值(64 位)。如果你有 100 万张卡片。这将占用 8 MB 内存。一旦您确定了哪些卡是赢家,您就可以确定谁是所有者。 (这可以存储在数据库中)

    假设您向美国的每个成年人出售一张卡片。 (AFAIK,从来没有彩票如此受欢迎)如果说每张一美元,你将带来 2 亿美元。您将需要 1.6 GB 的内存,它可以轻松装入 500 美元左右的 4 GB 服务器。可以肯定的是,您可以花 1000 美元购买一台 16 GB 的服务器。 ;)

    【讨论】:

      猜你喜欢
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多