722. 删除注释 - Kotlin 模拟

Smile_slime_47

Problem: 722. 删除注释

思路

直接模拟即可

为了方便注释的处理,这里没有用index in statement.indices()而是传统地创建了一个变量var index=0然后令while(index<statement.length){...index++},便于指针的跳跃

行注释的处理是比较简单的,主要是块注释需要考虑的情况比较复杂

用一个状态变量inBlockComment记录当前字符是否在块注释中

用一个字符串newStatement记录处理后的当前行内容,并在每次读取新行时重新初始化为空字符串。

每次读取字符时如果inBlockComment,则说明当前在块注释中,判断**当前字符是否为/以及上一个字符是否为***,若是则inBlockComment=false

  • 如果判断当前是否为*以及下一个字符是否为/的话,就需要在这里额外index++一下,防止将注释结束符中的/加进去

每次读取字符时如果!inBlockComment

  • 若**当前字符为/且下一个字符为/**,则直接跳过读取改行,即break即可
  • 若**当前字符为/且下一个字符为***,则设置inBlockComment=true,同时为了防止读取到/*/这种情况,应当令index直接跳到3个字符后,从而保证指针只会处理/**/的情况,由于我们每次循环都会进行一次index++,因此这里index+=2即可
  • 其他情况下可以直接将读取到的字符加在newStatement后面

然后我们会发现样例有一种情况是错误的:

1
2
3
abc/*
...
*/def

这种情况下,跨行的块注释应当被合并为一行,即abcdef,因此我们应当在读取新行时判断inBlockComment如果在读取新行时仍在块注释中,则不进行换行,即不对newStatement进行初始化操作

正则表达式的做法大同小异,主要是各语言调用的API不同,这里不再赘述

复杂度

  • 时间复杂度:

  • 空间复杂度:

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
fun removeComments(source: Array<String>): List<String> {
val ret = ArrayList<String>()
var inBlockComment = false
var newStatement = ""
var index: Int

for (statement in source) {
if (!inBlockComment) newStatement = ""
index = 0
loadChar@ while (index < statement.length) {
when {
inBlockComment ->
if (index - 1 >= 0 && statement[index] == '/' && statement[index - 1] == '*') inBlockComment = false
!inBlockComment ->
when {
(index + 1 < statement.length && statement[index] == '/' && statement[index + 1] == '/') -> break@loadChar
(index + 1 < statement.length && statement[index] == '/' && statement[index + 1] == '*') -> {
inBlockComment = true
index += 2
}
else -> newStatement += statement[index]
}
}
index++
}
if (!inBlockComment && newStatement.isNotEmpty()) ret.add(newStatement)
}

return ret
}
}
Comments
On this page
722. 删除注释 - Kotlin 模拟