leetcode
leetcode 601 ~ 650
删除注释

删除注释

难度:

标签:

题目描述

代码结果

运行时间: 29 ms, 内存: 16.0 MB


/* 
 * 思路:
 * 使用Java Stream API来简化遍历过程,
 * 同时仍然使用标志变量isBlockComment来处理块注释。
 */
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Solution {
    public List<String> removeComments(String[] source) {
        StringBuilder newLine = new StringBuilder();
        boolean[] isBlockComment = {false}; // Using array for mutable boolean
        return Arrays.stream(source)
                .map(line -> {
                    StringBuilder currentLine = new StringBuilder();
                    for (int i = 0; i < line.length(); i++) {
                        if (isBlockComment[0]) {
                            if (i + 1 < line.length() && line.charAt(i) == '*' && line.charAt(i + 1) == '/') {
                                isBlockComment[0] = false;
                                i++;
                            }
                        } else {
                            if (i + 1 < line.length() && line.charAt(i) == '/' && line.charAt(i + 1) == '*') {
                                isBlockComment[0] = true;
                                i++;
                            } else if (i + 1 < line.length() && line.charAt(i) == '/' && line.charAt(i + 1) == '/') {
                                break;
                            } else {
                                currentLine.append(line.charAt(i));
                            }
                        }
                    }
                    if (!isBlockComment[0] && currentLine.length() > 0) {
                        return currentLine.toString();
                    } else {
                        return null;
                    }
                })
                .filter(line -> line != null && !line.isEmpty())
                .collect(Collectors.toList());
    }
}

解释

方法:

这个题解是用迭代的方式来处理每一行代码。它维护了一个布尔变量 in_block_comment 来表示当前是否处于块注释中,以及一个字符串 current_line 来存储当前正在构建的有效代码行。通过遍历每一行代码中的每个字符,根据不同的情况来判断是否需要忽略某些字符: 1. 如果当前不在块注释中,并且遇到了 /* ,则进入块注释状态; 2. 如果当前在块注释中,并且遇到了 */ ,则退出块注释状态; 3. 如果当前不在块注释中,并且遇到了 // ,则忽略该行的剩余部分; 4. 如果当前不在块注释中,则将当前字符加入 current_line 。 在处理完每一行后,如果当前不在块注释中并且 current_line 不为空,则将 current_line 加入结果列表 result ,并清空 current_line 以便处理下一行。

时间复杂度:

O(n * m)

空间复杂度:

O(n)

代码细节讲解

🦆
在实现中,如果`/*`后紧跟`*/`(如`/**/`),算法如何确保这种情况下正确退出块注释状态?
在算法实现中,当检测到`/*`时,会立即进入块注释状态,并将索引`i`增加以跳过`/*`。接下来的迭代中,如果紧接着出现`*/`,即使它们是连续的,算法也会识别并处理这种情况。具体来说,当`i`和`i+1`位置上的字符是`*/`时,它会将`in_block_comment`标志设为`false`并将`i`再次增加,从而正确退出块注释状态。因此,无论`/*`和`*/`是否紧密相连,算法都能正确处理块注释的开始和结束。
🦆
题解中提到,如果在块注释中遇到`//`,则会被忽略。请问如果在行注释中遇到`/*`,该如何处理?
根据算法的逻辑,当遇到行注释标志`//`,算法会忽略该行剩余的所有字符,包括任何出现的`/*`。这意味着,在行注释开始之后的所有内容,无论是另一个注释的开始符号还是其他任何字符,都会被算法忽视,不会对块注释状态造成影响。因此,如果在`//`之后出现`/*`,它将被视为行注释的一部分并被忽略。
🦆
算法在判断进入块注释(`/*`)时,同时增加了索引`i`,这是否意味着在退出块注释(`*/`)后,紧接着的字符会被忽略?
在算法中,每次识别到块注释的开始(`/*`)或结束(`*/`)时,`i`会增加以跳过这两个字符。这确保了`/*`和`*/`本身不会被加入到最终的代码行中。但是,紧跟在`*/`之后的字符不会被忽略;索引`i`在处理完`*/`后会指向`*/`之后的下一个字符,然后继续正常处理这些字符。只有当结束块注释的同时达到行的末尾,后续字符才不会被处理,但这是由于行的结束,而非注释处理逻辑本身。
🦆
在处理完每一行后,如果还处于块注释状态,当前行的有效代码(如果有)是否会被错误地丢弃?
根据算法的设计,如果在处理完一行后仍处于块注释状态,该行中任何在块注释开始之前的有效代码都不会被添加到最终的结果中。`current_line`仅在不处于块注释状态时才会被添加到结果列表`result`中。这意味着,即使在块注释开始之前的部分有有效代码,如果块注释没有在该行结束,这部分代码也会被丢弃,只有当块注释结束后,后续行中的代码才会被处理并可能被添加到结果中。

相关问题

迷你语法分析器

给定一个字符串 s 表示一个整数嵌套列表,实现一个解析它的语法分析器并返回解析的结果 NestedInteger

列表中的每个元素只可能是整数或整数嵌套列表

 

示例 1:

输入:s = "324",
输出:324
解释:你应该返回一个 NestedInteger 对象,其中只包含整数值 324。

示例 2:

输入:s = "[123,[456,[789]]]",
输出:[123,[456,[789]]]
解释:返回一个 NestedInteger 对象包含一个有两个元素的嵌套列表:
1. 一个 integer 包含值 123
2. 一个包含两个元素的嵌套列表:
    i.  一个 integer 包含值 456
    ii. 一个包含一个元素的嵌套列表
         a. 一个 integer 包含值 789

 

提示:

  • 1 <= s.length <= 5 * 104
  • s 由数字、方括号 "[]"、负号 '-' 、逗号 ','组成
  • 用例保证 s 是可解析的 NestedInteger
  • 输入中的所有值的范围是 [-106, 106]

三元表达式解析器

三元表达式解析器