我有一个包含数十万个元素的字符串列表(文件)。 所有字符串的长度都是 10.
每个字符串可以有 58 个固定值之一。
列表片段示例:
NORMAL
NORMAL
NORMAL
NORMAL
NORMAL
HUNT_GROUP
CALL_TRANS
RING_BACK
CALL_TRANS
HUNT_GROUP
NORMAL
NORMAL
FWD_NOREPL
NORMAL
HUNT_GROUP
CALL_TRANS
RING_BACK
NORMAL
CALL_TRANS
HUNT_GROUP
HUNT_GROUP
NORMAL
HUNT_GROUP
HUNT_GROUP
CALL_TRANS
HUNT_GROUP
HUNT_GROUP
CALL_TRANS
RING_BACK
CALL_TRANS
NORMAL
FWD_UNCOND
我想将字符串值转换为整数,例如NORMAL -> 1,CALL_TRANS -> 3,RING_BACK -> 19,HUNT_GROUP -> 11 等等,按照记录。
使用运算符 CASE 的第一个想法非常慢:
case S of
'NORMAL ': I:=1;
'CALL_TRANS': I:=3;
'RING_BACK ': I:=19;
'HUNT_GROUP': I:=11;
'FWD_NOREPL': I:=7;
'FWD_UNCOND': I:=6;
'FWD_BUSY ': I:=5;
. . .
end;
与循环相同(A:array[0..57] of string[10],包含所有可能的值):
for J:=0 to 57 do
if S=A[J] then begin
I:=J;
break;
end;
如果对字符串列表进行预处理,结果会更好一些,最常见的值放在 CASE 运算符或数组的开头。
我希望这个任务是一个众所周知的任务,有一个很好的解决方案。虽然找不到...
一些想法。
比较整个字符串很慢。迭代所有 58 个值很慢。
我们用字符串S的第一个字符作为整数数组A1[A..Z]的索引,特殊填充,后面解释。
那么如果S='FWD_NOREPL',则S[1]='F'且A1[F]=5.
因此我们缩小了可能值的列表,因为只有 3 个字符串以“F”开头。 为了最终确定字符串,我们应该检查第 5 个字符串字符,因为 3 个不相同。
数组 A1 是一个预定义的常量,包含下一个要检查的字符串字符的数量 A1[F]=5.
如果 S[1]='F',则 S[5] 可以是 'N'、'U' 或 'B'。对于 S='FWD_NOREPL' S[5]='N'。现在字符串 100% 由 2 个字符确定。
所以 A1 给出了一个索引,接下来要检查哪个字符。
A2[A..Z] 包含转换的最终整数值:A2[N]=7, A2[U]=6, A2[B]=5.
1
1234567890
FWD_NOREPL -> 7
FWD_UNCOND -> 6
FWD_BUSY -> 5
|
S[1]=F
A1[F]=5
S[5]=N
A2[N]=7
所以问题是以一种聪明的确定性方式构建 A1 和 A2。我希望这个任务也应该有一个已知的解决方案。
最后我们不需要比较字符串和迭代 58 个值。
索引上的两次短“跳转”提供了必要的值。这应该很快。
长度为 10 的 58 个字符串的列表看起来像一个 10x58 矩阵。也许代数可以提供帮助?
问题是想出一个好的算法。它不特定于任何编程语言。虽然我更喜欢 Pascal(Lazarus)。