A 有一个包含许多全名 (>20000) 的列表,并且随着每个新注册的增加而增加。我需要按字母顺序为每个寄存器创建一个七位数的标识号,以便转换从 0100000 开始,到 9999999 结束。此号码必须基于全名和您的订单。
当添加新名称并将它们合并到现有基础中时,也会生成合并的新数字。
我还没有开发出一个好的算法来解决这个问题。然后我需要为此创建一个 PHP 脚本。
它是名称到数字的转换,但具有定义的范围。
例如
安东尼·费尔德:0.459.789
比安卡购物中心:0.989.432
丹东主教:2.986.999
马里奥·科尔特斯:7.883.120
保罗·路德:8.788.454
泽塔琼斯:9.987.001
插入了一个新名字:
奥古斯都诺维尔:0.589.223
弗雷德里克·弗朗西斯·福特·科波拉:3.765.453
最佳答案
您将遇到问题,因为最终您将添加到 August zzzzzperson 将获得编号 0.989.432 并且已经存在的许多记录。
如果您不希望添加太多新人,您可以做什么: 如果 Augustus Novell 被添加到您的数据库中 - 找出他应该放在哪两个名字之间(按字母顺序)。 安东尼·费尔德:0.459.789 比安卡购物中心:0.989.432
捕获他们的数字并在两者中间找到一个数字: roundUp((0.459.789 + 0.989.432)/2) = 0.724.611
只要您在开始时在每条记录之间留出明显的空隙即可。在此示例中,当您不断在 Anthony Felder 和最新添加的名称之间添加新名称时,您只能执行此操作 20 次。增加差距,增加你可以这样做的次数。但是你必须将差距扩大一倍,才能在其中获得一个额外的名字。
20 的限制只有在连续使用相同名称 20 次作为上限或下限时才有效。很想听听是否有更智能的算法,但我对此表示怀疑,无需重建索引。取两个数字的中间可确保您始终拥有两个数字之间的最大差距。 (不考虑预测模型)。
我不喜欢取平均值的解决方案,但我认为这可能是最佳解决方案。换句话说,除非有人提出更好的算法,否则我会尝试以不同的方式对您的情况进行排序。例如,放弃将数字按名称的字母顺序顺序排列的需要(我想知道为什么无论如何都需要这样做)
编辑:另一种选择。将他们的名字映射到一个数字 a = 01, b = 02, c = 03... z = 26, 空格 = 27
可选,空格是一个点,但你也可以每隔3个字母(6个数字)放一个点 这意味着 2 个同名的人会得到相同的号码。您可以通过让前两个数字告诉您是哪个人来解决这个问题。 所以第一个 Anthony Felder 将从 01 开始,第二个 Anthony Felder 从 02 开始,第三个 Anthony Felder 从 03 开始,然后开始映射 A (=01)。
- 您必须定义如何处理其他字符,例如 é。
- 这导致数字具有可变长度
- 这可能导致 LONG 数字。
- 同名人数限制为 99 人(如果以 00 开头,则为 100 人)
关于php - 按顺序创建标识号,范围定界到寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55253383/