我的任务是将名称目录拆分为四个(大约)相等的块。该目录实际上是一个已经alphebatised的电话簿。解决方案必须是通用的,适用于任何目录,而不仅仅是一个特定目录。如果它有助于该目录是一个字符串数组。
例如,一个目录的四个块可以是:
A-E, F-L, M-S and T-Z
虽然另一个可能是
A-B, C-D, E-F and G-Z
我已经考虑过将目录的大小分成4,然后向上计数直到达到该数字并注意到该条目开头的字母,但这并不是特别优雅。
我的意思是:将目录作为100个条目。我可以将它除以4得到25(每个块中应该有多少条目)。通过条目到25然后获取该条目应该给我第一个块中的最后一个条目。但是,当字母表中每个字母的条目数差异很大时,这不起作用。 A-J可能都有一个条目,K可能有32个条目,这将使我的过程无用。
使用伪代码而不是特定的C实现会很有帮助,但实际上正确方向上的一点将是一个很大的帮助。
答案 0 :(得分:1)
这是三个变量的优化问题;四个块之间的界限。如果我们用块半开区间A
- x 表示 x , y , z 的边界em>, xy , yz , z - Z
那么唯一的另一个约束是 x< = y < = z ,为 x,y,z 提供3276种可能性,无穷无尽地搜索。
然后你只需要一种方法就可以将一种配置评为优于另一种配置;我建议使用平方误差之和,例如对于块长度20, 26, 32, 24
,平方误差为(20-25)^2 + (26-25)^2 + (32-25)^2 + (24-25)^2 = 76
。
将它们组合在一起,您可以使用嵌套循环编写详尽的搜索:
best, best_error = Nothing, +Inf
for A <= x <= Z:
for x <= y <= Z:
for y <= z <= Z:
error = (sum(lengths[i] for A < i <= x) - 25)^2
+ (sum(lengths[i] for x < i <= y) - 25)^2
+ (sum(lengths[i] for y < i <= z) - 25)^2
+ (sum(lengths[i] for z < i <= Z) - 25)^2
if error < best_error:
best, best_error = (x, y, z), error
答案 1 :(得分:0)
目录已经排序。所以你可以很容易地将它们分成四个,如果你考虑额外的字母作为键(A-Ae,Af-Az等)。基本的想法是