所以情况就是这样...我得到了一些对象,每个对象都标有唯一的整数 id,对于这些对象的每一个组合,我需要创建新的对象,每个对象都有独特的ids。问题是该对象列表是动态的,在无状态环境中使用,因此每次运行时新生成的id必须相同。
为了让我更清楚我需要的东西,可以将对象数组视为其id的数组,例如:[10,7,23]。基本上,我需要获得所有可能组合的ID:
10,7
10,23
7,23
10,7,23
这里重要的是每个不同组合的生成ID必须相同(例如:10和7应始终生成相同的id)。此外,新添加的对象不应影响以前生成的ID。因此,例如,稍后当某个新对象添加到该列表中时,从先前组合生成的ID必须与添加新对象之前保持一致。
目前,我有一个解决方案,几乎归结为由于组合ID的总和而生成新的id,因此产生的ID是:
17个
33个
30个
40
当然,这种方法可以产生重复的ID,这就是我要求一些更复杂的算法的建议的原因。我还尝试为新生成的id引入1000的固定偏移量,并将总和与组合对象的数量相乘,例如结果ID为1034(1000+(10 + 7)* 2),1066(1000+(10 + 23) )* 2)等,但我不确定它是否会使我免于重复。 :)
清楚地提到,我需要这个用于某些PHP项目,但由于这个问题不是特定于语言的,我希望有一些优秀的数学家可以带来一些好的解决方案。 :)
有用的信息是,组合ID在10000-99999范围内,组合的最大项目数不超过10个。
请注意,我不需要如何从数组元素中进行所有组合的解决方案,而只需要用于生成整数id的“公式”。
提前致谢。
答案 0 :(得分:2)
不确定你的目标是什么,但我会去...
您是否尝试过使用字符键?例如,10,7,3变成具有下划线的序列。每个序列都有一个唯一的哈希值。
$arrayOfKeys = array(10, 7, 3);
$hash = implode('_', $arrayOfKeys);
print $hash;
# 10_7_3
我个人会采用这种简单的方法。如果您正在使用数据库并且您每天不生产100k记录,那么使用索引(主键或唯一)varchar字段应该非常快。
如果你要创建数字,这里有一个提示:取最大数字的长度,这将是你的序列的前缀,例如:
10, 5, 1 -> 2100501
105, 45, 201 -> 3105045201
前缀将告诉您以下序列的长度。我无法想到你会得到双打......任何人? ;)
希望它有所帮助...
答案 1 :(得分:0)
第1步:对获得的值进行排序。 例如:如果你得到10,7或7,10,那么在进入ID发生器之前应该得到7,10。如果您知道数字的范围,即假设[0-100]使用基数或计数排序,则会很快。
步骤2:将数字表示为字符串,由任何选择的分隔符分隔。(':')也许。 例如:对于7,10 id将变为“7:10”。
正在进行排序以避免为10,7和7,10生成不同的ID。
BTW这些数字代表什么?
答案 2 :(得分:0)
除非你允许标签长度增加,否则我认为这是不可能的。
假设您最多有N
个不同的对象,与N
个不同的标签相对应。
如果您希望能够代表所有可能的对,假设一对中的顺序无关紧要,您可能需要N.(N-1)/2
个额外标签,无论它们是什么,您都需要保留它们。
对于所有三元组N.(N-1).(N-2)/6
,对于所有四元组N.(N-1).(N-2).(N-3)/24
...
这会以指数方式增长,并且很快就会超过整数的容量。
任何其他尝试压缩标签空间的解决方案(例如散列)都会导致冲突。您可以通过维护冲突表来解决冲突,但这会破坏“生成的ID必须与每次运行相同”的要求。