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 = ; i < line.size(); ++i) {
if (!blocked) {
if (i == line.size() - ) out += line[i];
else {
string t = line.substr(i, );
if (t == "/*") blocked = true, ++i;
else if (t == "//") break;
else out += line[i];
}
} else {
if (i < line.size() - ) {
string t = line.substr(i, );
if (t == "*/") blocked = false, ++i;
}
}
}
if (!out.empty() && !blocked) {
res.push_back(out);
out = "";
}
}
return res;
}
};

类似题目:

Ternary Expression Parser

Mini Parser

参考资料:

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

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

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

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

  1. [LeetCode] Remove Element 移除元素

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  2. [LeetCode] Remove 9 移除9

    Start from integer 1, remove any integer that contains 9 such as 9, 19, 29... So now, you will have ...

  3. [LeetCode] Remove Boxes 移除盒子

    Given several boxes with different colors represented by different positive numbers. You may experie ...

  4. [Swift]LeetCode722. 删除注释 | Remove Comments

    Given a C++ program, remove comments from it. The program source is an array where source[i] is the  ...

  5. 【LeetCode】722. Remove Comments 解题报告(Python)

    [LeetCode]722. Remove Comments 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/remove-c ...

  6. LeetCode 722. Remove Comments

    原题链接在这里:https://leetcode.com/problems/remove-comments/ 题目: Given a C++ program, remove comments from ...

  7. 【leetcode】722. Remove Comments

    题目如下: Given a C++ program, remove comments from it. The program source is an array where source[i] i ...

  8. LeetCode:Remove Duplicates from Sorted List I II

    LeetCode:Remove Duplicates from Sorted List Given a sorted linked list, delete all duplicates such t ...

  9. LeetCode:Remove Duplicates from Sorted Array I II

    LeetCode:Remove Duplicates from Sorted Array Given a sorted array, remove the duplicates in place su ...

随机推荐

  1. Konckout第一个实例:简单数据模型绑定

    Konck是什么: http://www.aizhengli.com/knockoutjs/50/knockout.html 使用:直接引入knockout.js文件 第一个实例:实现输入框输入值改变 ...

  2. 获取服务器时间js代码

    function getSevertime(){ var xmlHttp = new XMLHttpRequest(); if( !xmlHttp ){ xmlHttp = new ActiveXOb ...

  3. Spring Boot入门教程2-1、使用Spring Boot+MyBatis访问数据库(CURD)注解版

    一.前言 什么是MyBatis?MyBatis是目前Java平台最为流行的ORM框架https://baike.baidu.com/item/MyBatis/2824918 本篇开发环境1.操作系统: ...

  4. javaAPI中的常用 类 以及接口

    java.lang包中的常用类以及接口 类 1. Integer :Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的字段. 2. Math ...

  5. Dom属性方法

    一.javascript的三大核心 1.ECMAScript js的语法标准 2.DOM Document object Model 文档对象模型,提供的方法可以让js操作html标签 3.BOM B ...

  6. Mysql 一次性备份导出/导入恢复所有数据库

    有木有遇到过这种情况?电脑或者服务器需要重装系统?可是你电脑上存着n多个网站的数据库,怎么办?把数据库文件夹拷贝出来,重装系统之后再拷回去?如果你使用了InnoDB引擎,恐怕那样做会出麻烦的,一个一个 ...

  7. java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用

    先来讲解一下Semaphore信号灯的作用:  可以维护当前访问自身的线程个数,并提供了同步机制, 使用semaphore可以控制同时访问资源的线程个数 例如,实现一个文件允许的并发访问数. 请看下面 ...

  8. iOS开发-OC数据类型

    以下是OC中的实例,Swift部分不适用 iOS中的注释 // 单行注释 // 注释对代码起到解释说明的作用,注释是给程序员看的,不参与程序运行 /*  多行注释   Xcode快捷键   全选 cm ...

  9. .net 小程序获取用户UnionID

    第一次写博客,写的不好多多海涵! 1.小程序获取UnionID的流程用code去换取session_key,然后去解密小程序获取到的那串字符! 话不多说,原理大家都懂!!!!!! 直接上代码 publ ...

  10. 《javascript设计模式与开发实践》阅读笔记(16)—— 状态模式

    状态模式 会区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变.比如电灯的开关是开还是关,在外界的表现就完全不同. 电灯例子 按照常规思路,实现一个电灯就是构造一个电灯类,然后指定一下它的 ...