【问题标题】:Unique identifier with smallest base possible, without collisions on old/new set of data具有可能最小基数的唯一标识符,不会在旧/新数据集上发生冲突
【发布时间】:2020-05-22 20:50:18
【问题描述】:

我收到一棵或多棵节点树。

节点上可能有也可能没有 ID 属性。

目前我正在遍历树并在没有 ID 属性的节点上添加随机的 8 位数字。因为我预计树中的节点不会超过 10k,所以发生冲突的机会非常小。

我仍在考虑如何最好地将 ID 的长度减少到 4 位,同时确保一棵树中没有冲突。我想到的是遍历将现有 ID 收集到 Set 中的树一次,然后在检查 Set 是否没有冲突时再次添加新 ID。必须为每棵树重置集合。

如果有更高效的方法来实现这一点,我将不胜感激您对此事的意见和建议。

附录 A:

我正在考虑以下(简化的 0-9)问题。如果我有一组现有 ID [0, 1, 2, 5, 8, 9] 我将不得不生成随机数,直到我得到例如4(无碰撞)我担心在较大的 Set 上会有点慢,而且肯定不是最佳路线。

【问题讨论】:

  • 这是一棵树。您在插入时不知道您是否在复制现有节点吗?
  • @RobertHarvey 我收到一棵树,其中一些节点有,而其他节点没有 ID。我希望所有人都拥有 UniqueID。
  • 我会改写我的问题。您现有的树是如何知道将每个节点放在哪里的?
  • @RobertHarvey 我没有关于这些树最初是如何构建的信息。通过使用 ID,我可以轻松添加孩子/兄弟姐妹。
  • 你为什么不走你现有的树并建造一棵新的?

标签: javascript typescript uniqueidentifier


【解决方案1】:

这里你有一个非常简单的方法,它会为你生成一个具有给定 MAX 范围的未使用数字数组。

const MAX = 30;
const usedNumbers = [3, 4, 12, 13, 14, 16, 23, 27];

// https://stackoverflow.com/questions/3746725/how-to-create-an-array-containing-1-n
const notUsedNumbers = Array.from(Array(MAX), (_, i) => i+1).filter(i => !usedNumbers.includes(i));

console.log(notUsedNumbers);

并链接到小提琴:https://jsfiddle.net/L9r6anq1/

【讨论】:

  • 这是一个有趣的解决方案,虽然难以阅读,而且在较大范围内非常缓慢,几乎无法使用。
  • @radulle 你说的非常慢是什么意思?最多 4 位数字 10000 从快速测试中,在我的浏览器中,执行它需要大约 25 - 40 毫秒。 jsfiddle.net/x39L0utm/1你想有什么样的表现?
  • 当我尝试运行它时,它花费了更多时间并且 Chrome 挂起,我将不得不重新检查,如果我沿着这条路走,我必须每棵树都做一次,而不是保持该数组在内存中并在需要时移动它。
  • 也许不是 ID 生成是一个真正的问题,而是您在节点上执行的一些额外操作?我鼓励您使用performance API 来精确测量部分代码的执行时间。无论如何,如果您不想复制 ID,那么您需要将已经使用的 ID 存储在某个地方并比较您已经使用的 ID 是否被占用。或者您需要根据需要覆盖所有 ID,这样您就会知道有没有重复。
【解决方案2】:

随机选择的 10^8 种可能性意味着您有 50% 的机会与仅 10^4 个对象发生碰撞(请参阅生日悖论);这不是“非常小”的几率。将 10^4 个对象的可能性减少到只有 10^4 种,这意味着当你接近尾声时,碰撞将接近 100%,如果你有一天有 10k+1 个对象,则永远不会终止。

一般来说,如果您想使用相对较短的 ID 空间,您将需要一个非常高效的冲突检测系统,例如将所有已分配(或未分配)的值保存在暂存器中,或者只是放弃随机分配值并按顺序进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    相关资源
    最近更新 更多