我需要帮助来解决这个编码难题。
让函数HTMLElements(str)读取所传递的str参数,该参数将是HTML DOM元素和纯文本的字符串。将使用的元素包括:B、i、em、div、p。例如:如果str是"<div><b><p>hello world</p></b></div>"
,那么这个DOM元素的字符串是正确嵌套的,所以程序应该返回字符串true。
如果字符串嵌套不正确,则返回遇到的第一个元素,如果将其更改为其他元素,则会生成格式正确的字符串。如果字符串格式不正确,则只需更改一个元素。例如:如果str是"<div><i>hello</i>world</b>"
,那么程序应该返回字符串div,因为如果第一个元素被更改为<b>
,字符串将被正确格式化。
例如:
第一个
以下是我的进展:
function HTMLElements(str) {
let openingTag = str.match(/<\w+>/g)
let closingTag = str.match(/(<\/\w+>)/g)
let strObj = {
'<div>': '</div>',
'<p>': '</p>',
'<i>': '</i>',
'<p>': '</p>',
'<em>': '</em>',
'<b>': '</b>',
}
let unclosedElem = []
for(let i=0; i<openingTag.length; i++){
console.log(closingTag)
if(closingTag.indexOf(strObj[openingTag[i]]) ===-1){
unclosedElem.push(closingTag.splice(closingTag.indexOf(strObj[openingTag[i]]),1))
}
}
console.log(unclosedElem)
if(unclosedElem.length === 0) return true;
return unclosedElem[0]
}
// keep this function call here
HTMLElements("<div><div><b><b/></div></p>")
现在我明白这远远不能解决问题,但我想这对我来说是一个开始。我最终会解决这个问题,但感谢你的投入
7条答案
按热度按时间gblwokeq1#
有几个问题。
首先,你要做
closingTag.indexOf(...) === -1
,如果它等于-1
,就意味着这个结束标记根本没有找到,但是要求是“检测一个问题”,即使结束标记在这里,但是顺序不对 (嵌套不正确)。因此,您可以做的第一个修正是:
这将从结束标记数组的末尾向后计数。因为first开始标记对应于last结束标记。
但是,我们遇到了一个问题。
indexOf
将返回标签的第次出现。但是,如果我们有多个div
标签嵌套在彼此的内部呢?它将不知道你引用的是哪一个。我的建议是,在开始标签数组中从左到右排列,而在结束标签数组中从右到左排列,而不是使用
indexOf
。一个简单的方法是对第二个数组使用.reverse()
,这样就可以在相同的方向上使用这两个数组:u4vypkhs2#
我已经研究了一个替代的解决方案,基于blex发布的一个。作为一个说明,这个方法没有考虑标签是否是畸形的,所以可能有必要注意这一点。
hkmswyz63#
进一步研究blex的解决方案,以说明
<div>abc</div><p><em><i>test test test</b></em></p>
等大小写字符串,其中div标签立即打开和关闭,并且没有任何其他标签嵌套在其中。但是当我更深入地思考这个问题并考虑到**“如果一个字符串没有正确嵌套,返回遇到的第一个元素,如果将其更改为不同的元素,将导致一个格式正确的字符串。如果字符串格式不正确,那么它将只是一个需要更改的元素”**,这个条件确实有帮助,知道它只能是一个没有正确嵌套的元素👌🏾也就是说,我认为更好的解决方案和方法是:
另一种方法是使用字典对标签进行频率计数,并对不符合的标签进行比较:
我不确定哪一个是最快的,但是考虑到性能、空间和时间复杂性以及可读性,我肯定会选择第二个或第三个解决方案。我想我最终会选择第三个解决方案,因为第三个解决方案可以在
O(n)
中运行,而第二个解决方案不一定能在O(n)
中运行,但看起来更像O(n * m)
。由于for循环中的嵌套拼接,更类似于二次时间。这里有很多要讨论和考虑的因素,但最终,你可以只做定时测试,并选择一个超过另一个真的🤷🏾♂️ulmd4ohb4#
下面是python对此问题的解决方案:
z5btuh9x5#
使用PHP
xcitsw886#
下面是一个完全相反的方向,如果节点嵌套正确,它会删除它们,直到所有节点都被删除(这样我们就知道它们都是正确嵌套的),或者当它发现嵌套不正确的节点时,它会返回第一个可以更改的节点来纠正问题。
bkkx9g8r7#
下面是使用Stack而不是regex的另一种方法。
1.我们想创建一个方法
converStringToList
。这将需要作为使用regex
的替换。1.然后在
htmlElements
方法中,我想示例化一个堆栈,一个openTags
和closeTags
的数组,一个名为res的字符串和converStringToList
。1.我们迭代
converStringToList
并检查current是否为openTag
,如果是,则压入堆栈。1.如果current是
closeTag
,并且openTag
中堆栈peek的索引等于closeTag
中current的索引,则将其从堆栈中弹出,因为它们匹配1.如果current是一个
closeTag
,并且openTag
中的stack peek的索引不等于closeTag
中的current的索引,则我们满足条件并返回stack peek。htmlElement
方法converStringToList
方法