我的一个客户希望为他的项目使用唯一的代码(长篇故事......),他问我解决方案。代码将包含4个部分,其中第一个是发送项目的邮政编码,第二个是供应商注册号,第三个是发送项目的年份,最后一个是三个分裂字母数字独特的字符。
正如您所看到的,前三个部分是静态字段,在同一年中对于同一发件人永远不会更改。所以我们可以说最后一部分是该年的标识符部分。这部分是3分区的alpahnumeric,意思是从000开始到ZZZ结束。
问题是我的客户出于某些合理的原因希望这部分不是顺序的。例如,这不是他想要的:
06450-05-2012-000
06450-05-2012-001
06450-05-2012-002
...
06450-05-2012-ZZY
06450-05-2012-ZZZ
最后一部分应随机产生:
06450-05-2012-A17
06450-05-2012-0BF
06450-05-2012-002
...
06450-05-2012-T7W
06450-05-2012-22C
但它也应该是非重复性的。因此,一旦生成了可能的id,就应该从选择池中丢弃该可能性。
我正在寻找一种有效的方法。
你能提出更有效的建议吗?我将使用C#进行编码,将MS SQL用于数据库..
答案 0 :(得分:4)
如果您希望为每个zip-supplier-year元组创建远小于36^3
个条目,您应该只为最后一个字段选择一个随机值,然后检查它是否存在,如果它存在则重复确实
即使您创建了最大可能条目数的一半,新条目仍然只有一个失败的预期值。假设您的数据库是根据整体标识符编制索引的,那么这个代价就不算太高了。
也就是说,如果您希望使用除了几个可能的标识符之外的所有标识符,那么您应该提前创建所有可能的记录。这可能听起来像是一个高成本,但内存中存储未使用记录的每个空间最终都会存储真实记录。
我希望第一种情况更有可能,但如果没有,或者如果还有其他两种组合,请添加评论以及更多信息,我会修改我的答案。
答案 1 :(得分:4)
我认为选项取决于将要使用的代码量:
如果您希望在一年内使用其中大部分,那么最好预先生成。如果做得好,查找应该非常快。无论如何,你的数据库每年将有1.679.616项,所以你必须做正确的事情。
另一方面,你期望使用其中大部分是否好?如果突然有多于预期的项目,它可能会让你没有代码。
如果您希望只使用少量,那么随机+存在检查可能是一种方法,但不清楚它应该是多少才能做到最好(我很确定它是可能的虽然计算了这一点。
答案 2 :(得分:4)
如果它不一定是随机的,你可以简单地选择一个固定但“不可预测”的加数,这对于26 + 10 == 36 == 2²·3²
是相对优先的。这意味着,只需选择一个既不能被2
也可以3
整除的固定加数。
每次需要新的序列号时,请继续将此固定号码添加到以前的序列号中。当然,这要以模46656
(或1679616
}为模。
数学保证你不会两次得到相同的数字(在没有剩下“免费”数字之前)。
作为加数,您可以使用const int addend = 26075
,因为它是5
模6
。