Swati Patil
Swati Patil

Reputation: 19

string expansion algo in python

I'm trying to write code which does following using python3. input 3[as] = asasas input 3[b2[ac]] = bacacbacacbacac

I'm not getting something right with substrings. Any help appreciated.

Here is my code -

def parse_string(pattern) :
    if len(pattern) == 0 :
        return
    
    open_bracket = []
    close_Bracket = []
    
    for i in range(len(pattern)) :
        if (pattern[i] == '[') :
            open_bracket.append(i)
        if (pattern[i] == ']') :
            close_Bracket.append(i)
            
    print("open brackets - ", open_bracket)
    print("Closed bracket ", close_Bracket)
    
    rev = open_bracket[::-1]
    outputstr = {}
    index = 0
    for i in range(len(rev)) :
        token = pattern[rev[i]+1:index+close_Bracket[i]]
        multiplier = pattern[rev[i]-1:rev[i]]
        #build new string
        new_str = int(multiplier) * (token)
        pattern = pattern.replace(pattern[rev[i]-1:index+close_Bracket[i]+1], new_str)
        index = index + len(new_str) - 3 - len(token) # 4 sums up to replacing open and close bracket and number -1
        outputstr[pattern[rev[i]-1:close_Bracket[i]+1]] = new_str 

which produces output - bacacac]bacacac] for input 2[b3[ac]]. Is there a better way to get the output? TIA

Edit The edited code now works and produces output as expected. I think Daniel's answer below is clean and readable.

Upvotes: 1

Views: 123

Answers (2)

Swati Patil
Swati Patil

Reputation: 19

Actually, found answer. I just fixed the index part to

index = index + len(new_str) - 3 - len(token)

Upvotes: 0

Daniel Hao
Daniel Hao

Reputation: 4980

Two versions presented here as alternative of "better" approach, first using stack (more intuitive), second using re module (that I came across). Since the definition of "better" is not clear, these just for cross reference/to be considered and commented.

But the first version is more readable and faster than PO.

def parseString(s: str):
    curnum = 0
    curstring = ''
    stack = []
     for char in s:
         if char == '[':
             stack.append(curstring)
             stack.append(curnum)
             curstring = ''
             curnum = 0
         elif char == ']':
             prenum = stack.pop()
             prestring = stack.pop()
             curstring = prestring + prenum * curstring
         elif char.isdigit():
              curnum = curnum * 10 + int(char)
         else:
             curstring += char
        return curstring

  import re
  def parseString(s: str) -> str:
      while '[' in s:
              s = re.sub(r'(\d+)\[([a-z]*)\]', lambda m: int(m.group(1)) * m.group(2), s)
     return s
    

Upvotes: 1

Related Questions