我有一个数据库,我想在其中存储特定元素的任意顺序。有问题的数据库不支持订单集,所以我必须自己做。
执行此操作的一种方法是为元素的位置存储浮点值,然后在插入新元素时获取周围元素的平均位置:
Item A - Position 1
Item B - Position 1.5 (just inserted).
Item C - Position 2
现在,由于各种原因我不想使用花车,我想用字符串代替。例如:
Item A - Position a
Item B - Position aa (just inserted).
Item C - Position b
我希望尽可能缩短这些字符串,因为它们永远不会“整理”。
有人能建议一种尽可能高效,紧凑地生成此类字符串的算法吗?
谢谢,
添
答案 0 :(得分:1)
将“am”或“an”位置分配给项目B并使用二进制除法步骤进行其他插入是合理的。 这类似于26-al数字系统,其中'a'..'z'符号对应于0..25。
a b //0 1
a an b //insert after a - middle letter of alphabet
a an au b //insert after an
a an ar au b //insert after an again (middle of an, au)
a an ap ar au b //insert after an again
a an ao ap ar au b //insert after an again
a an ann ao... //insert after an, there are no more place after an, have to use 3--symbol label
....
a an anb... //to insert after an, we treat it as ana
a an anan anb // it looks like 0 0.5 0.505 0.51
二叉树结构的伪代码:
function InsertAndGetStringKey(Root, Element): string
if Root = nil then
return Middle('a', 'z') //'n'
if Element > Root then
if Root.Right = nil then
return Middle(Root.StringKey, 'z')
else
return InsertAndGetStringKey(Root.Right, Element)
if Element < Root then
if Root.Left = nil then
return Middle(Root.StringKey, 'a')
else
return InsertAndGetStringKey(Root.Left, Element)
Middle(x, y):
//equalize length of strings like (an, anf)-> (ana, anf)
L = Length(x) - Length(y)
if L < 0 then
x = x + StringOf('a', -L) //x + 'aaaaa...' L times
else if L > 0 then
y = y + StringOf('a', L)
if LL = LastSymbol(x) - LastSymbol(y) = +-1 then
return(Min(x, y) + 'n') // (anf, ang) - > anfn
else
return(Min(x, y) + (LastSymbol(x) + LastSymbol(y))/2) // (nf, ni)-> ng
答案 1 :(得分:0)
如上所述,问题没有解决方案。一旦算法为相邻元素生成字符串'a'和'aa',就没有可以在它们之间插入的字符串。这是该方法的致命问题。此问题与用于字符串的字母表无关:如果您愿意,请将“a”替换为“使用的字母表中的第一个字母”。
当然,当达到这个僵局时,可以通过更改其他元素的排序字符串来解决它,但这似乎超出了OP的要求。
我认为问题等同于找到一个整数来表示一个元素的顺序,并发现35和36已经用于命令现有元素。无论你多么努力,都没有35到36之间的整数。
使用实数或计算机近似值,例如浮点数或有理数。
编辑以回应OP的评论
只需调整算法以添加2个有理数:(a / b)+(c / d)=(ad + cb)/ bd。拿(ad + cb)/ 2(如果你想要或需要四舍五入)你在前两个中间有一个合理的中间位置。
答案 2 :(得分:0)
资本是一种选择吗?
如果是这样,我会用它们在相邻的值之间插入。
例如插入之间 一个 AA
你可以这样做:
一
aAaa&lt; ---这个上限。告诉我们在相邻的小值之间还有一个地方.ie。一个[AA]一个
AABA
AACA
ABAA
ABBA
AA
现在,如果你需要在a和aAaa之间插入
你可以做到
一
aAAaaa&lt; --- 2 caps。告诉我们在相邻的小值之间还有两个位置,即[AAaa] a
aAAaba
aAAaca
...
aAAbaa
AAAA
在紧凑或高效方面,我没有提出任何要求......