将预定义字符串列表转换为整数数组的算法

问题描述 投票:0回答:0

我有一个包含数十万个元素的字符串列表(文件)。 所有字符串的长度都是 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)。

arrays algorithm linear-algebra
© www.soinside.com 2019 - 2024. All rights reserved.