# Time: O(n), n is the length of the source # Space: O(k), k is the max length of a line # 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. class Solution(object): def removeComments(self, source): """ :type source: List[str] :rtype: List[str] """ in_block = False result, newline = [], [] for line in source: i = 0 while i < len(line): if not in_block and i+1 < len(line) and line[i:i+2] == '/*': in_block = True i += 1 elif in_block and i+1 < len(line) and line[i:i+2] == '*/': in_block = False i += 1 elif not in_block and i+1 < len(line) and line[i:i+2] == '//': break elif not in_block: newline.append(line[i]) i += 1 if newline and not in_block: result.append("".join(newline)) newline = [] return result