• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
LilyLiya
博客园    首页    新随笔    联系   管理    订阅  订阅
Underscorify Substring
flag = 0, 1的巧妙变换!!!

refer to: AlgoExpert

Input: string, substring

Output: add underscore at the start and the end of substring found in the string. if overlap or sit side by side, only add underscore at the leftmost and the rightmost positions

 

Analysis: 

step 1

 

 step 2

 

 step 3

 

 time and space complexity

 

 

string.find: O(m+n)

traverse length n

upperbound: n(m+n)

def underscorifySubstring(string, substring):
    locations = collapse(getLocations(string, substring))
    return underscorify(string, locations)

def getLocations(string, substring):
    locations = []
    startIdx = 0;
    while startIdx < len(string):
        nextIdx = string.find(substring, startIdx);
        if nextIdx != -1: #if substring is found, add the start index and the end index
            locations.append([nextIdx, nextIdx + len(substring)])
            startIdx = nextIdx + 1 #continue to traverse the next one
        else:
            break # if not found, break
    return locations

def collapse(locations): # address the special cases: 1. overlap 2. sit side by side
    if not len(locations): # if the locations array is empty, return []
        return locations
    newLocations = [locations[0]] # newLocations starts from the first element in the 2d array
    previous = newLocations[0] #initiate the previous(the first position)
    for i in range(1, len(locations)): # check the following positions
        current = locations[i] #current defines the following position, from the second array in locations
        if current[0] <= previous[1]: #[1,3] [2,4] current[0] = 2, previous[1] = 3, overlapping
            previous[1] = current[1] #[1,3]->[1,4] # update previous
        else: # no overlapping or sit side by side
            newLocations.append(current) # append the whole currect array
            previous = current # update the previous to current
    return newLocations

def underscorify(string, locations): # add underscore
    locationsIdx = 0
    stringIdx = 0
    inBetweenUnderscores = False
    finalChars = []
    i = 0
    while stringIdx < len(string) and locationsIdx < len(locations): # while we are in the middle od string and the locations array
        if stringIdx == locations[locationsIdx][i]:
            finalChars.append("_")
            inBetweenUnderscores = not inBetweenUnderscores # finished adding _ for one array
            if not inBetweenUnderscores: #false(initial)-> true -> false(one pass finished, move to another) -> true->false
                locationsIdx += 1 # go to the next array
            i = 0 if i == 1 else 1 # if i =1, ->i = 0;   if i = 0, ->i = 1, i have two potions: 0 or 1
        finalChars.append(string[stringIdx]) # if stringIdx != locations[locationsIdx][i], append the substring directly
        stringIdx += 1
    if locationsIdx < len(locations): # finished traversing the string 
        finalChars.append("_")
    elif stringIdx < len(string): # finished traversing the locations
        finalChars.append(string[stringIdx:])
    return "".join(finalChars)

 

 
posted on 2021-05-27 08:29  LilyLiya  阅读(92)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3