• 给字符串添加加粗标签(AC自动机+Python)


    可以暴力解决,但是为了锻炼一下ac自动机的编程,我们使用ac自动机。

    ac自动机主要维护两个列表,一个列表ch,ch[f][idx]表示从父节点f向idx这个方向走,走到的节点。另一个列表nex,nex[i]表示节点i回跳边的节点。

    1. from collections import defaultdict, deque
    2. class Solution:
    3. def addBoldTag(self, s: str, words: List[str]) -> str:
    4. p = ''.join(words)
    5. n = len(p)
    6. n1 = len(s)
    7. r1 = []
    8. # ac自动机
    9. ch = defaultdict(dict)
    10. nex = [0]*(n+1)
    11. cnt = [0]*(n+1)
    12. idy = 0
    13. def assign(s):
    14. if s.isdigit():
    15. return int(s)
    16. elif ord('a') <= ord(s) <= ord('z'):
    17. return ord(s) - ord('a') + 10
    18. else:
    19. return ord(s) - ord('A') + 36
    20. def insert(word):
    21. f = 0
    22. nonlocal idy
    23. for s in word:
    24. idx = assign(s)
    25. if idx not in ch[f]:
    26. idy += 1
    27. ch[f][idx] = idy
    28. f = idy
    29. else:
    30. f = ch[f][idx]
    31. cnt[f] = len(word)
    32. def bulid():
    33. qu = deque()
    34. for i in range(62):
    35. if i not in ch[0]:
    36. continue
    37. qu.append(ch[0][i])
    38. while qu:
    39. f = qu.popleft()
    40. for i in range(62):
    41. if i not in ch[f]:
    42. ch[f][i] = 0 if i not in ch[nex[f]] else ch[nex[f]][i]
    43. else:
    44. nex[ch[f][i]] = 0 if i not in ch[nex[f]] else ch[nex[f]][i]
    45. qu.append(ch[f][i])
    46. def query(s):
    47. f = 0
    48. for i in range(n1):
    49. idx = assign(s[i])
    50. f = 0 if idx not in ch[f] else ch[f][idx]
    51. idy = f
    52. while idy != 0:
    53. if cnt[idy]:
    54. r1.append([i-cnt[idy]+1, i+1])
    55. break
    56. idy = nex[idy]
    57. return
    58. for word in words:
    59. insert(word)
    60. bulid()
    61. query(s)
    62. r1.sort()
    63. leth = len(r1)
    64. if leth == 0:return s
    65. rec = [r1[0]]
    66. for idx in range(1, leth):
    67. l, r = r1[idx]
    68. if l <= rec[-1][1]:
    69. rec[-1][1] = max(r, rec[-1][1])
    70. else:
    71. rec.append([l,r])
    72. dic = defaultdict(str)
    73. for l, r in rec:
    74. dic[l] = ''
    75. dic[r] = ''
    76. ans = ''
    77. for idx in range(n1):
    78. if dic[idx]:
    79. ans += dic[idx]
    80. ans += s[idx]
    81. if dic[n1]:
    82. ans += dic[n1]
    83. return ans

    确实是通过了,但是!!!暴力解法居然比ac自动机更快!!!哪边出了问题???

    下面是暴力的,上面是ac自动机

    暴力代码:

    1. class Solution:
    2. def addBoldTag(self, s: str, words: List[str]) -> str:
    3. from collections import defaultdict
    4. r1 = []
    5. l1 = len(s)
    6. for word in words:
    7. l2 = len(word)
    8. for idx in range(l1-l2+1):
    9. if s[idx:idx+l2] == word:
    10. r1.append([idx,idx+l2])
    11. r1.sort()
    12. leth = len(r1)
    13. if leth == 0:return s
    14. rec = [r1[0]]
    15. for idx in range(1, leth):
    16. l, r = r1[idx]
    17. if l <= rec[-1][1]:
    18. rec[-1][1] = max(r, rec[-1][1])
    19. else:
    20. rec.append([l,r])
    21. dic = defaultdict(str)
    22. for l, r in rec:
    23. dic[l] = ''
    24. dic[r] = ''
    25. ans = ''
    26. for idx in range(l1):
    27. if dic[idx]:
    28. ans += dic[idx]
    29. ans += s[idx]
    30. if dic[l1]:
    31. ans += dic[l1]
    32. return ans

  • 相关阅读:
    (三)行为模式:8、状态模式(State Pattern)(C++示例)
    每日一题 2591. 将钱分给最多的儿童
    Spring,SpringMVC,SpringBoot,SpringCloud有什么区别?
    qt绘图事件
    【大模型系列】问答理解定位(Qwen-VL/Llama2/GPT)
    2022面试相关 - react相关原理
    Spark的一些问题汇总 及 Yarn与Spark架构的对比
    写个rpc调用,试试自己了解多少
    python urllib 爬虫库简单说明
    YOLO物体检测-系列教程1:YOLOV1整体解读(预选框/置信度/分类任/回归任务/损失函数/公式解析/置信度/非极大值抑制)
  • 原文地址:https://blog.csdn.net/W_extend/article/details/138083125