2016-06-14 53 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 
相關問題