https://leetcode.com/problems/mini-parser/
def iol_parser(string, start, brackets):
if string[start] == '[':
eol = brackets[start]
return listarg_parser(string, start + 1, eol - 1, brackets), eol + 1
else:
# print(string[start:])
idx = start
while idx < len(string) and string[idx] != ',' and string[idx] != ']':
idx += 1
return int(string[start : idx]), idx
def listarg_parser(string, start, end, brackets):
arg, argend = iol_parser(string, start, brackets)
args = [arg]
# print(arg)
while argend < end:
arg, argend = iol_parser(string, argend + 1, brackets)
args.append(arg)
return args
class Solution:
def deserialize(self, s: str) -> NestedInteger:
stack = []
brackets = {}
for i, e in enumerate(s):
if e == '[':
stack.append(i)
elif e == ']':
brackets[stack.pop()] = i
ret = iol_parser(s, 0, brackets)[0]
#print(ret)
return NestedInteger(ret)
versus
class Solution:
def deserialize(self, s):
stack, num, last = [], "", None
for c in s:
if c.isdigit() or c == "-": num += c
elif c == "," and num:
stack[-1].add(NestedInteger(int(num)))
num = ""
elif c == "[":
elem = NestedInteger()
if stack: stack[-1].add(elem)
stack.append(elem)
elif c == "]":
if num:
stack[-1].add(NestedInteger(int(num)))
num = ""
last = stack.pop()
return last if last else NestedInteger(int(num))
Another example is in this problem, Given an encoded string in form of "ab[cd]{2}def"
return decoded string "abcdcddef".
The recursive solution is as follows
from collections import deque
def parse(s, start, end, brackets):
idx = start
builder = []
while idx < end:
c = s[idx]
if c == '[':
int_start = brackets[idx] + 2
int_len = s[int_start:].index('}')
integer = int(s[int_start : int_start + int_len])
builder.append(
parse(s, idx + 1, brackets[idx], brackets) * integer
)
idx = brackets[idx] + 2 + int_len + 1
else:
builder.append(c)
idx += 1
return ''.join(builder)
def decodeString2(s: str) -> str:
brackets = {}
stack = []
for i, c in enumerate(s):
if c == '[':
stack.append(i)
if c == ']':
brackets[stack.pop()] = i
return parse(s, 0, len(s), brackets)
The stack based solution is a lot shorter, even though it's a little bit harder to come up with --
def decodeString(s):
stk = []
cur = ""
num = 0
for ch in s:
if ch.isdigit():
num = num*10 + int(ch)
elif ch.isalpha():
cur += ch
elif ch == "(":
stk.append(cur)
cur = ""
elif ch == "}":
pre = stk.pop()
cur = pre + cur*num
num = 0
while stk:
cur = stk.pop() + cur
return cur