【LeetCode 算法】Remove Comments 删除注释-模拟

文章目录

  • Remove Comments 删除注释
    • 问题描述:
    • 分析
    • 代码
    • Tag

Remove Comments 删除注释

问题描述:

给一个 C++ 程序,删除程序中的注释。这个程序source是一个数组,其中source[i]表示第 i 行源码。 这表示每行源码由 ‘\n’ 分隔。

在 C++ 中有两种注释风格,行内注释和块注释。

字符串// 表示行注释,表示//和其右侧的其余字符应该被忽略。
字符串/* 表示一个块注释,它表示直到下一个(非重叠)出现的*/之间的所有字符都应该被忽略。(阅读顺序为从左到右)非重叠是指,字符串/*/并没有结束块注释,因为注释的结尾与开头相重叠。
第一个有效注释优先于其他注释。

如果字符串//出现在块注释中会被忽略。
同样,如果字符串/*出现在行或块注释中也会被忽略。
如果一行在删除注释之后变为空字符串,那么不要输出该行。即,答案列表中的每个字符串都是非空的。

样例中没有控制字符,单引号或双引号字符。

比如,source = “string s = “/* Not a comment. */”;” 不会出现在测试样例里。
此外,没有其他内容(如定义或宏)会干扰注释。

我们保证每一个块注释最终都会被闭合, 所以在行或块注释之外的/*总是开始新的注释。

最后,隐式换行符可以通过块注释删除。 有关详细信息,请参阅下面的示例。

从源代码中删除注释后,需要以相同的格式返回源代码。

1 < = s o u r c e . l e n g t h < = 100 0 < = s o u r c e [ i ] . l e n g t h < = 80 s o u r c e [ i ] 由可打印的 A S C I I 字符组成。 每个块注释都会被闭合。 给定的源码中不会有单引号、双引号或其他控制字符。 1 <= source.length <= 100\\ 0 <= source[i].length <= 80\\ source[i] 由可打印的 ASCII 字符组成。\\ 每个块注释都会被闭合。\\ 给定的源码中不会有单引号、双引号或其他控制字符。 1<=source.length<=1000<=source[i].length<=80source[i]由可打印的ASCII字符组成。每个块注释都会被闭合。给定的源码中不会有单引号、双引号或其他控制字符。

分析

一个模拟问题.

对于每一行代码,有可能存在注释,块注释或者是行注释.
也可能不存在注释,但是需要注意即使本行不存在注释,它也有可能属于块注释的一部分.

如果之前没有出现过块注释,那么接下来的代码中可能出现 纯代码 , 第一个块注释,行注释,代码+注释等,

  • 纯代码,就是决对不会出现 / / , / ∗ //,/* //,/, 由于之前没有注释,所以这里不会出现 ∗ / */ /.
  • 行注释,此位置后的都可以忽略。
  • 第一部分块注释,即 / ∗ /* /会出现,那么需要找到他的结尾 ∗ / */ /,end 可能在当前行尾,或者是下面的某行中。

为了解决这个问题,官方的思路,比较精简,它将块注释使用标记,那么字符要么在注释内,要么不在注释内。而行注释可以直接删除后面的内容。

  • 如果 i n B l o c k = t r u e , inBlock=true, inBlock=true,表示处于块注释中,非注释标记的字符都不会加入字符串,而且只需要关心是否会遇到*/,从而结束块注释。
  • 如果 i n B l o c k = f a l s e , inBlock=false, inBlock=false,表示不在块注释中,也就是说 当前行中可能有代码,也有可能有行注释,当然也有可能遇到 块注释的开始位置。

如果一行处理完成,只有当不处于块注释的状态下并且字符串不为空的情况下,才会进行输出,同时还要清空字符串。

代码

public List<String> removeComments(String[] source) {
        boolean inBlock = false;
        StringBuilder newline = new StringBuilder();
        List<String> ans = new ArrayList();
        for (String line: source) {
            int i = 0;
            char[] chars = line.toCharArray();
            if (!inBlock) newline = new StringBuilder();
            while (i < line.length()) {
                if (!inBlock && i+1 < line.length() && chars[i] == '/' && chars[i+1] == '*') {
                    inBlock = true;
                    i++;
                } else if (inBlock && i+1 < line.length() && chars[i] == '*' && chars[i+1] == '/') {
                    inBlock = false;
                    i++;
                } else if (!inBlock && i+1 < line.length() && chars[i] == '/' && chars[i+1] == '/') {
                    break;
                } else if (!inBlock) {
                    newline.append(chars[i]);
                }
                i++;
            }
            if (!inBlock && newline.length() > 0) {
                ans.add(new String(newline));
            }
        }
        return ans;
    }

时间复杂度 O ( M N ) O(MN) O(MN)

空间复杂度 O ( M N ) O(MN) O(MN)

Tag

Array

String

你可能感兴趣的:(数据结构与算法,算法,leetcode)