<p>我相信您当前代码中的问题源于这样一个事实:您可以在一行中有多个backspace,但是您只查看“一”个字符。(这一点我可能错了,我没有用pdb检查代码。)</p>
<p>正如评论中所建议的,解决这个问题的一个好方法是将其分为以下两部分。你知道吗</p>
<ol>
<li>规范化/规范化两个输入字符串。这意味着一次处理一个字符,从每个字符串中去掉backspace和前面的相关字符。你知道吗</li>
<li>比较两个规范化的字符串。你知道吗</li>
</ol>
<p>步骤2很简单,只需使用python中内置的stringcompare方法(==)。你知道吗</p>
<p>步骤1有点困难,因为在输入字符串的一行中可能有多个backspace。处理这个问题的一种方法是建立一个新的字符串,一次一个字符,然后在每个空格上删除最后添加的字符。下面是一些示例代码。你知道吗</p>
<pre><code>def canonicalize(s):
normalized_s = ""
for i, c in enumerate(s):
# Check for a backspace, taking care not to run off the end of the string.
if c == BACKSPACE:
normalized_s = normalized_s[:-1]
else:
normalized_s += c
return normalized_s
</code></pre>
<p>这种方法的一个很好的副作用是,前导的backspace不会导致任何错误,它们被忽略了。稍后我将尝试在其他实现中保留此属性。在c++这样的语言中,可以修改字符串,这样的代码可以变得非常有效,因为这类似于将指针和条目更改为char数组。你知道吗</p>
<p>在python中,每次编辑都会创建一个新字符串(或者至少不能保证它不会分配一个新字符串)。我认为关注自己的堆栈(也就是一个由字符组成的数组,指针指向末尾)可以产生更好的代码。在python中有几种管理堆栈的方法,最常见的是列表,另一个好的选择是收藏.deque. 除非分析人员另有说明,否则我会选择更熟悉的列表。你知道吗</p>
<pre><code>def canonicalize(s):
normalized_s = list()
for c in s:
# Check for a backspace, taking care not to run off the end of the string.
if c == BACKSPACE:
if normalized_s:
normalized_s.pop()
else:
normalized_s.append(c)
return "".join(normalized_s)
</code></pre>
<p>最后的比较方法可能看起来像</p>
<pre><code>def compare(s1, s2):
return canonicalize(s1) == canonlicalize(s2)
</code></pre>
<hr/>
<p>上面的代码有两个问题。首先,它几乎可以保证创建两个新字符串。第二个是它需要对字符串进行四次总的传递,每个输入字符串一次,每个清理过的字符串一次。你知道吗</p>
<p>这可以通过向后而不是向前改进。通过向后迭代,可以看到backspaces,并提前知道哪些字符将被删除(read-ignored或skipped)。我们一直这样做,直到出现不匹配,或者至少有一个字符串的字符用完为止。这种方法需要更多的簿记,但不需要额外的空间。它只使用两个指针跟踪每个字符串的当前进度,并使用一个计数器跟踪要忽略的字符数。下面给出的代码不是特别python的,它可以做得更好。如果你要用两台发电机和一台izipèu,你可以把所有的样板都去掉。你知道吗</p>
<pre><code>def compare(s1, s2):
i, j = len(s1) - 1, len(s2) - 1
while i >= 0 or j >= 0:
ignore = 0
while i >= 0:
if s1[i] == BACKSPACE:
ignore += 1
elif ignore > 0:
ignore -= 1
else:
break
i -= 1
ignore = 0
while j >= 0:
if s2[j] == BACKSPACE:
ignore += 1
elif ignore > 0:
ignore -= 1
else:
break
j -= 1
if i < 0 and j < 0:
# No more characters to try and match
return True
if (i < 0 and j >= 0) or (i >= 0 and j < 0):
# One string exhausted before the other
return False
if s1[i] != s2[j]:
return False
i -= 1
j -= 1
return True
</code></pre>
<hr/>
<p><strong>编辑</p>
<p>下面是我为compare的上一个实现尝试的一些测试用例。你知道吗</p>
<pre><code>true_testcases = (
("abc", "abc"),
("abc", "abcde\b\b"),
("abcdef", "\b\babcdef\bf"),
("", "\b\b\b"),
("Toronto", "Torooo\b\bntt\bo"))
false_testcases = (
("a", "a\b"),
("a", "a\b\b"),
("abc", "abc\bd\be"),
)
print([eq(s1, s2) for s1, s2 in true_testcases])
print([eq(s1, s2) for s1, s2 in false_testcases])
</code></pre>