2016-06-14 54 views
1

我正在将一个vt100(oldschool终端)实现为lua,它运行在嵌入式MCU上。性能是一个问题。高效地搜索字符串中的一组字符并返回第一个匹配

Given是一个包含多个(不可预知的数字)字符的字符串(输入行)。 在这个字符串中,我想从一组字符中找到第一个匹配项。

例如:

-- ASCII value(hex) of keyboard keys. 
#define KEY_UP  "\x41" 
#define KEY_DOWN "\x42" 
#define KEY_RIGHT "\x43" 
#define KEY_LEFT "\x44" 

-- terminal object is defined and created 

function terminal:receive() 
    -- Set buffer and shorthand to self.port.read 
    local read = function() return self.port:read() end 
    local received = "" 

    while true do 
     -- Read Input 
     local line = read() 
     if (not line) then break end 
     received = received .. line 

     -- Search for the key. 
     -- Don't search in line, due different baudrates might not 
     -- Get the entire digit at once. 
     if (received:find(KEY_UP)) then 
      return KEY_UP 
     elseif (received:find(KEY_DOWN)) then 
      return KEY_DOWN 
     ... and so on 
     end 
    end 
end 

在我的例子中的解决方案是一种缓慢的,肯定。要想出更高性能的解决方案并不难。但是,对此,最高性能的解决方案是什么?

+0

您是否使用过任何分析器?你确定模式匹配部分是这里的性能瓶颈吗? –

+0

这可能不是,但那是另一个问题。 – Sempie

+0

由于我正在寻找像40个键,所以我只是乍一看而已。如果这场比赛是第一把钥匙之一,它肯定会安静得很快,接收过程可能是瓶颈。但是,如果没有匹配,就会有40:find(),这会花费更多的时间。 – Sempie

回答

0

你可以制作一个包含你正在寻找的所有字符的模式。然后您可以捕获结果并返回。

如果您正在寻找的角色中没有任何优先顺序,

1

由于所有匹配项都是一个字符长,因此您可以使用集[]来匹配并捕获()以查看您的匹配结果。

#define KEY_UP  "\x41" 
#define KEY_DOWN "\x42" 
#define KEY_RIGHT "\x43" 
#define KEY_LEFT "\x44" 
-- assemble pattern once for performance 
local KEY_pattern = "([" .. KEY_UP .. KEY_DOWN .. KEY_RIGHT .. KEY_LEFT .. "])" 

-- ............... skipped ............... 
local match_start, match_end, match_content = received:find(KEY_pattern) 
if (match_content) then 
    return match_content 
end 
相关问题