[LeetCode] Remove Comments 移除注释

Given a C++ program, remove comments from it. The program source is an array where source[i] is the i-th line of the source code. This represents the result of splitting the original source code string by the newline character \n.

In C++, there are two types of comments, line comments, and block comments.

The string // denotes a line comment, which represents that it and rest of the characters to the right of it in the same line should be ignored.

The string /* denotes a block comment, which represents that all characters until the next (non-overlapping) occurrence of */ should be ignored. (Here, occurrences happen in reading order: line by line from left to right.) To be clear, the string /*/ does not yet end the block comment, as the ending would be overlapping the beginning.

The first effective comment takes precedence over others: if the string // occurs in a block comment, it is ignored. Similarly, if the string /* occurs in a line or block comment, it is also ignored.

If a certain line of code is empty after removing comments, you must not output that line: each string in the answer list will be non-empty.

There will be no control characters, single quote, or double quote characters. For example, source = "string s = "/* Not a comment. */";" will not be a test case. (Also, nothing else such as defines or macros will interfere with the comments.)

It is guaranteed that every open block comment will eventually be closed, so /* outside of a line or block comment always starts a new comment.

Finally, implicit newline characters can be deleted by block comments. Please see the examples below for details.

After removing the comments from the source code, return the source code in the same format.

Example 1:

Input:
source = ["/*Test program */", "int main()", "{ ", "  // variable declaration ", "int a, b, c;", "/* This is a test", "   multiline  ", "   comment for ", "   testing */", "a = b + c;", "}"]

The line by line code is visualized as below:
/*Test program */
int main()
{
  // variable declaration
int a, b, c;
/* This is a test
   multiline
   comment for
   testing */
a = b + c;
}
Output: ["int main()","{ ","  ","int a, b, c;","a = b + c;","}"]
The line by line code is visualized as below:
int main()
{
int a, b, c;
a = b + c;
}
Explanation:
The string /* denotes a block comment, including line 1 and lines 6-9. The string // denotes line 4 as comments.

Example 2:

Input:
source = ["a/*comment", "line", "more_comment*/b"]
Output: ["ab"]
Explanation: The original source string is "a/*comment\nline\nmore_comment*/b", where we have bolded the newline characters.  After deletion, the implicit newline characters are deleted, leaving the string "ab", which when delimited by newline characters becomes ["ab"].

Note:

  • The length of source is in the range [1, 100].
  • The length of source[i] is in the range [0, 80].
  • Every open block comment is eventually closed.
  • There are no single-quote, double-quote, or control characters in the source code.

这道题让我们移除代码中的注释部分,就是写代码中经常遇到的两种注释,单行注释和多行注释,也可以叫块注释,当然最最重要的就是要找到这两种注释的起始标识符"//"和"/*",注意它们两者之间存在覆盖的关系,谁在前面谁work,比如"//abc/*",那么此时后面的块注释起始符被忽略掉,同样"/*abc//",后面的单行注释起始符也不起作用,所以两者之间的前后顺序很重要。博主刚开始想的方法是用string的find函数来分别找"//"和"/*"的起始位置,如果不存在就返回-1,但是需要分多种情况来处理,其是否存在,还有二者的前后顺序,处理起来比较麻烦。起始我们可以直接按字符来一个一个处理,由于块注释是多行注释,所以一旦之前有了块注释的起始符,当前行的处理方式就有所不同了,所以我们需要一个变量blocked来记录当前是否为块注释状态,初始化为false。建立空字符out,用来保存去除注释后的字符。然后我们遍历整个代码的每一行,遍历每一行中的每一个字符,如果当前字符是最后一个字符了,说明不会再有注释了,将当前字符加入out中,否则取出当前位置和下一个位置的两个字符,如果其正好是"/*",说明之后的部分都是块注释了,我们将blocked赋值为true,然后指针向后移动一个,明明两个字符啊,为啥只移动一个呢,因为另一个可以在for循环中的++i移动;如果当前两个字符正好是"//",说明当前行之后都是注释,我们并不care后面有啥,所以可以直接break掉当前行;如果都不是,说明当前字符是代码,将其加入out中。好,下面来看blocked为true的情况,说明之后的内容都是块注释的内容,我们唯一关心的是有没有结束符"*/",所以还是先做判断,如果当前不是最后一个字符,说明至少还有两个字符,然后取出两个字符,如果正好是块注释结束符,那么我们将标识重置为false,指针要后移动一个。当前行遍历完后,如果out不为空,且blocked为false,则将out存入结果res中,参见代码如下: 

class Solution {

public:
    vector<string> removeComments(vector<string>& source) {
        vector<string> res;
        bool blocked = false;
        string out = "";
        for (string line : source) {
            for (int i = 0; i < line.size(); ++i) {
                if (!blocked) {
                    if (i == line.size() - 1) out += line[i];
                    else {
                        string t = line.substr(i, 2);
                        if (t == "/*") blocked = true, ++i;
                        else if (t == "//") break;
                        else out += line[i];
                    }
                } else {
                    if (i < line.size() - 1) {
                        string t = line.substr(i, 2);
                        if (t == "*/") blocked = false, ++i;
                    }
                }
            }
            if (!out.empty() && !blocked) {
                res.push_back(out);
                out = "";
            }
        }
        return res;
    }
};

参考资料:

https://discuss.leetcode.com/topic/109943/c-easy-solution

https://discuss.leetcode.com/topic/109637/c-o-n-one-pass

本文转自博客园Grandyang的博客,原文链接:[LeetCode] Remove Comments 移除注释

,如需转载请自行联系原博主。

时间: 2024-09-26 21:51:16

[LeetCode] Remove Comments 移除注释的相关文章

[LeetCode] Remove Invalid Parentheses

Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. Note: The input string may contain letters other than the parentheses ( and ). Examples: "()())()" -> ["()()()",

[LeetCode] Remove Linked List Elements

Remove all elements from a linked list of integers that have value val. Example Given: 1 –> 2 –> 6 –> 3 –> 4 –> 5 –> 6, val = 6 Return: 1 –> 2 –> 3 –> 4 –> 5 解题思路 定义两个指针pre和cur,如果cur的值为val,则删除该结点.需要注意的情况有两种:①需要删除头结点:②链表为空. 实现

[LeetCode] Remove Duplicates from Sorted List - 链表问题

题目概述:Given a sorted linked list, delete all duplicates such that each element appear only once.For example,Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3. 题目解析:这是一道非常简单的链表题目,题意是删除单链表(已排序)中的重复数字,只需一次判断前后两个结点数字是否相

Backbone.js 0.9.2 源码注释中文翻译版_基础知识

// Backbone.js 0.9.2 // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. // Backbone may be freely distributed under the MIT license. // For all details and documentation: // http://backbonejs.org (function() { // 创建一个全局对象, 在浏览器中表示为window对象, 在Node.j

LeetCode All in One 题目讲解汇总(持续更新中...)

终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 如果各位看官们,大神们发现了任何错误,或是代码无法通过OJ,或是有更好的解法,或是有任何疑问,意见和建议的话,请一定要在对应的帖子下面评论区留言告知博主啊,多谢多谢,祝大家刷得愉快,刷得精彩,刷出美好未来- 博主制作了一款iOS的应用"Leetcode Meet Me",里面有Leetcode上所有的题目,并且贴上了博主的解法,随时随地都能

移除UTF-8文件头的BOM

inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) UTF-8 BOM又叫UTF-8 签名,在UTF-8文件的头部,长度为3个字节.其实UTF-8 的BOM对UFT-8没有作用,BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别.但是在Eclipse中,带有BOM的java源码生成javadoc时却会出现如下错误:(来源:http://blog.cs

Word 2013中的注释和修订功能详解

微软Office 2013采用全新人性化设计,完美支持社交网络的同时,提供包括阅读.笔记.会议和沟通等现代应用场景,并可通过最新的云服务模式交付给用户.其中Word 2013组件提供了全新的阅读模式,该模式包含很多方便用户查看文档.注释和修订文档等方面的功能. Word 2013除了支持常规的内容输入编辑之外,还支持文档的注释和修订功能.注释功能是在不影响原文内容的情况下加入批注,对原文的内容进行注解;修订功能是将修改过的地方标注起来,以方便用户下次打开时告知那里进行过修改. Word 2013

Java 注释规范详解

在 Java 的编写过程中我们需要对一些程序进行注释,除了自己方便阅读,更为别人更好理解自己的程序,所以我们需要进行一些注释,可以是编程思路或者是程序的作用,总而言之就是方便自己他人更好的阅读. 注释类型 Java 有两类注释: implementation comments(实现注释)和 documentation comments(文档注释). 实现注释常见于 C++,使用 /*...*/,和 //.文档注释 (也称为"doc comments") 是 Java 独有的,使用 /*

《jQuery、jQuery UI及jQuery Mobile技巧与示例》——3.14 技巧:移除元素

3.14 技巧:移除元素 当使用detach()移除元素后,它会从屏幕和文档树中消失,但它还保存在内存中.代码清单3-14演示使用remove()和empty()函数把元素从文档和内存中删除.remove()函数会返回被移除的元素,所以可以把它们用变量保存起来,再将它们重新插入到页面中.请记住,当用remove()函数来这么做的时候,所有的jQuery数据和事件信息都会丢失. 代码清单3-14 演示remove()和empty()之间的区别 00 <!DOCTYPE html> 01 02 &