BFE.dev 有点像前端的leetCode,以下是我的刷题记录。

本文所涉的是 BFE.dev#55. HTML字符串中高亮关键字

剖析

题目的指标是用<em>高亮关键字,如下:

highlightKeywords(  'Hello FrontEnd Lovers',   ['Hello', 'Front', 'JavaScript'])// '<em>Hello</em> <em>Front</em>End Lovers'

看起来很简略,只须要找到关键字替换即可。不过遇到反复的状况就有点麻烦了,比方下:

highlightKeywords(  'Hello FrontEnd Lovers',   ['Front', 'FrontEnd', 'JavaScript'])// 'Hello <em>FrontEnd</em> Lovers'

我的想法是:

  1. 当咱们发现关键字时,比方上述例子中的'Front',咱们能够记录下首尾的index,startend
  2. 而后便历从startend开始的字符串,如果又发现关键词的时候,依据须要更新end,比方咱们有可能遇到 ontE,从而end被延后。
  3. 遇到end的时候进行,此时 startend之间的字符都须要高亮。

上述逻辑解决了反复的状况,那相邻的状况呢?比方这样:

highlightKeywords(  'Hello FrontEnd Lovers',   ['Front', 'End', 'JavaScript'])// 'Hello <em>FrontEnd</em> Lovers'

对于这种状况,咱们能够一直反复上述过程,而后找到可能的相邻的关键词即可。

代码

首先咱们解决如下一个子问题:

给定一个start index,返回其最长高亮关键词的end index。
没有的话返回-1

根据上述剖析,该问题能够比拟容易的解决,如下:

const keywordSet = new Set(keywords)const getEndForEm = (start) => {  let isEmFound = false  let end = start  // 如果找到新的关键词,就不断更新end  // 遇到end的时候进行  while (start <= end) {    for (let word of keywordSet) {      const length = word.length      if (html.slice(start, start + length) === word) {        isEmFound = true        end = Math.max(end, start + length - 1)      }    }    start += 1  }  return isEmFound ? end : -1}

OK,当初有了上述函数,问题变得比较简单。咱们只须要对于每一个index,循环调用上述函数失去最终间断区间即可。

let result = ''for (let i = 0; i < html.length;) {  let endForEm = getEndForEm(i)    // 查看是否有相邻关键词  while (endForEm > -1) {    const nextEndForEm = getEndForEm(endForEm + 1)    if (nextEndForEm === -1) {      break    }    endForEm = nextEndForEm  }    if (endForEm > -1) {    result += '<em>' + html.slice(i, endForEm + 1) + '</em>'    i = endForEm + 1  } else {    result += html[i]    i += 1  }}return result

通过撒花!

这是一个乏味的问题。

感激浏览。心愿能有所帮忙,

如果有趣味能够在 这里本人尝试一下。