高效地搜索一个字符串并返回第一个匹配的字符集

我正在将 vt100(老派终端)实现到运行在嵌入式 MCU 上的 lua 中。在这里,性能是一个问题。

给定一个包含数个(不可预知数量)字符的字符串(输入行)。在该字符串中,我想要找到字符集中的第一个匹配项。

例如:

-- 键盘按键的 ASCII 值(十六进制)
#define KEY_UP      "\x41"
#define KEY_DOWN    "\x42"
#define KEY_RIGHT   "\x43"
#define KEY_LEFT    "\x44"

-- 终端对象的定义和创建

function terminal:receive()
    -- 将缓冲区和快捷方式设置为 self.port.read
    local read = function() return self.port:read() end
    local received = ""

    while true do
        -- 读取输入
        local line = read()
        if (not line) then break end
        received = received .. line

        -- 搜索键。
        -- 由于不同的波特率可能不会
        -- 一次获得整个数字,因此不要在行中搜索。
        if (received:find(KEY_UP)) then
            return KEY_UP
        elseif (received:find(KEY_DOWN)) then
            return KEY_DOWN
        ...等等
        end
    end
end

我的示例中的解决方案比较慢,当然。想出更高效的解决方案并不难。但是,什么是最高效的解决方案?

点赞
用户88888888
用户88888888

你可以创建一个包含所有你要查找的字符的单一模式。然后,你可以捕获结果并返回它。

如果你要查找的字符之间没有优先顺序,那么这种方法是可行的。

2016-06-14 09:12:27
用户936986
用户936986

由于你所有的匹配只有一个字符,你可以使用集合[]来匹配和捕获()来查看你所匹配到的内容。

#define KEY_UP      "\x41"
#define KEY_DOWN    "\x42"
#define KEY_RIGHT   "\x43"
#define KEY_LEFT    "\x44"
-- 为了提高性能,只需一次组装模式
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
2016-06-14 09:20:59