Algorithm 括号查找算法lua?

Algorithm 括号查找算法lua?,algorithm,lua,Algorithm,Lua,我正在制作一个JSON解析器,我正在寻找一种算法,它可以找到所有匹配的括号([])和括号({}),并将它们放入一个表中,其中包含这对括号的位置 返回值的示例: table[x][firstPos][secondPos] = type table[x] = {firstPos, secondPos, bracketType} 编辑:让parse()作为返回括号对的函数。将table设为parse()函数返回的值。让codeString成为包含我要检测的括号的字符串。设firstPos为Nth对

我正在制作一个JSON解析器,我正在寻找一种算法,它可以找到所有匹配的括号(
[]
)和括号(
{}
),并将它们放入一个表中,其中包含这对括号的位置

返回值的示例:

table[x][firstPos][secondPos] = type

table[x] = {firstPos, secondPos, bracketType}
编辑:让
parse()
作为返回括号对的函数。将
table
设为
parse()
函数返回的值。让
codeString
成为包含我要检测的括号的字符串。设
firstPos
N
th对括号中第一个括号的位置。让
secondPos
成为
N
th对括号中第二个括号的位置。让
bracketType
为括号对的类型(“括号”或“括号”)

例如:

如果你打电话:

table = parse(codeString)

表[N][firstPos][secondPos]
将等于
类型

好吧,在普通Lua中,您可以这样做,同时考虑嵌套括号:

function bm(s)
    local res ={}
    if not s:match('%[') then
            return s
    end
    for k in s:gmatch('%b[]') do
            res[#res+1] = bm(k:sub(2,-2))
    end
    return res
end
当然,您可以很容易地将其概括为大括号、圆括号等(请记住模式中[]的必要转义,除了在%b模式后面)

如果您不局限于普通Lua,那么可以使用LPeg来获得更大的灵活性

如果您不是在寻找括号的内容,而是位置,那么递归方法更难实现,因为您应该跟踪您所在的位置。更简单的方法是在走线时穿过线并匹配它们:

function bm(s,i)
    local res={}
    res.par=res      -- Root
    local lev = 0
    for loc=1,#s do
        if s:sub(loc,loc) == '[' then
            lev = lev+1
            local t={par=res,start=loc,lev=lev}   -- keep track of the parent
            res[#res+1] = t                       -- Add to the parent
            res = t                               -- make this the current working table
            print('[',lev,loc)
        elseif s:sub(loc,loc) == ']' then
            lev = lev-1
            if lev<0 then error('too many ]') end -- more closing than opening.
            print(']',lev,loc)                  
            res.stop=loc                          -- save bracket closing position
            res = res.par                         -- revert to the parent.
        end
    end
    return res
end
功能bm(s,i)
本地res={}
res.par=res--根
本地lev=0
对于loc=1,我们可以
如果s:sub(loc,loc)='['则
列夫=列夫+1
本地t={par=res,start=loc,lev=lev}——跟踪父级
res[#res+1]=t——添加到父级
res=t——将其设为当前工作表
打印(“[”,lev,loc)
elseif s:sub(loc,loc)=']'然后
列夫=列夫-1

如果我想出了自己的算法

function string:findAll(query)
    local firstSub = 1
    local lastSub = #query
    local result = {}
    while lastSub <= #self do
        if self:sub(firstSub, lastSub) == query then
            result[#result + 1] = firstSub
        end
        firstSub = firstSub + 1
        lastSub = lastSub + 1
    end
    return result
end

function string:findPair(openPos, openChar, closeChar)
    local counter = 1
    local closePos = openPos
    while closePos <= #self do
        closePos = closePos + 1
        if self:sub(closePos, closePos) == openChar then
            counter = counter + 1
        elseif self:sub(closePos, closePos) == closeChar then
            counter = counter - 1
        end
        if counter == 0 then
            return closePos
        end
    end
    return -1
end

function string:findBrackets(bracketType)
    local openBracket = ""
    local closeBracket = ""
    local openBrackets = {}
    local result = {}
    if bracketType == "[]" then
        openBracket = "["
        closeBracket = "]"
    elseif bracketType == "{}" then
        openBracket = "{"
        closeBracket = "}"
    elseif bracketType == "()" then
        openBracket = "("
        closeBracket = ")"
    elseif bracketType == "<>" then
        openBracket = "<"
        closeBracket = ">"
    else
        error("IllegalArgumentException: Invalid or unrecognized bracket type "..bracketType.."\nFunction: findBrackets()")
    end
    local openBrackets = self:findAll(openBracket)
    if not openBrackets[1] then
        return {}
    end
    for i, j in pairs(openBrackets) do
        result[#result + 1] = {j, self:findPair(j, openBracket, closeBracket)}
    end
    return result
end

请看。您几乎肯定想使用递归。@H2CO3我不懂C,我正在寻找一种在Lua中实现它的方法。算法不依赖于语言。请检查并返回括号的位置。如果您这样做,那么我就不需要获取括号内的数据,因为我可以使用
sub()
函数。这将为我提供更大的灵活性。通过在
%b[]之前和之后放置空捕获
()
,可以很容易地更改此函数以返回括号的位置
pattern。不过,要让递归工作起来,还需要一些算法。这有点困难,但有了这个解决方案,你应该能够找到答案。这就是说,我会看到我这个周末有时间。在现场演示中,我得到了
input:22:'end'预期(关闭第1行的'function')在
附近。我将你的新函数与
打印(unpack(bm(“[hello[world]!”))放在一起进行测试。捕捉得好!确实缺少一个结尾。是否…刚刚更正了它
5   14
6   13
7   12
8   11
9   10