|
| 1 | +# Time: O(n), n is the length of the source |
| 2 | +# Space: O(k), k is the max length of a line. |
| 3 | + |
| 4 | +# Given a C++ program, remove comments from it. |
| 5 | +# The program source is an array where source[i] is the i-th line of the source code. |
| 6 | +# This represents the result of splitting the original source code string by the newline character \n. |
| 7 | +# |
| 8 | +# In C++, there are two types of comments, line comments, and block comments. |
| 9 | +# |
| 10 | +# The string // denotes a line comment, which represents that it and |
| 11 | +# rest of the characters to the right of it in the same line should be ignored. |
| 12 | +# |
| 13 | +# The string /* denotes a block comment, |
| 14 | +# which represents that all characters until the next (non-overlapping) occurrence of */ |
| 15 | +# should be ignored. (Here, occurrences happen in reading order: line by line from left to right.) |
| 16 | +# To be clear, the string /*/ does not yet end the block comment, as the ending would be overlapping the beginning. |
| 17 | +# |
| 18 | +# The first effective comment takes precedence over others: |
| 19 | +# if the string // occurs in a block comment, it is ignored. |
| 20 | +# Similarly, if the string /* occurs in a line or block comment, it is also ignored. |
| 21 | +# |
| 22 | +# If a certain line of code is empty after removing comments, |
| 23 | +# you must not output that line: each string in the answer list will be non-empty. |
| 24 | +# |
| 25 | +# There will be no control characters, single quote, or double quote characters. |
| 26 | +# For example, source = "string s = "/* Not a comment. */";" will not be a test case. |
| 27 | +# (Also, nothing else such as defines or macros will interfere with the comments.) |
| 28 | +# |
| 29 | +# It is guaranteed that every open block comment will eventually be closed, |
| 30 | +# so /* outside of a line or block comment always starts a new comment. |
| 31 | +# |
| 32 | +# Finally, implicit newline characters can be deleted by block comments. Please see the examples below for details. |
| 33 | +# |
| 34 | +# After removing the comments from the source code, return the source code in the same format. |
| 35 | +# |
| 36 | +# Example 1: |
| 37 | +# Input: |
| 38 | +# source = ["/*Test program */", "int main()", "{ ", " // variable declaration ", "int a, b, c;", "/* This is a test", " multiline ", " comment for ", " testing */", "a = b + c;", "}"] |
| 39 | +# |
| 40 | +# The line by line code is visualized as below: |
| 41 | +# /*Test program */ |
| 42 | +# int main() |
| 43 | +# { |
| 44 | +# // variable declaration |
| 45 | +# int a, b, c; |
| 46 | +# /* This is a test |
| 47 | +# multiline |
| 48 | +# comment for |
| 49 | +# testing */ |
| 50 | +# a = b + c; |
| 51 | +# } |
| 52 | +# |
| 53 | +# Output: ["int main()","{ "," ","int a, b, c;","a = b + c;","}"] |
| 54 | +# |
| 55 | +# The line by line code is visualized as below: |
| 56 | +# int main() |
| 57 | +# { |
| 58 | +# int a, b, c; |
| 59 | +# a = b + c; |
| 60 | +# } |
| 61 | +# Explanation: |
| 62 | +# The string |
| 63 | +# /* |
| 64 | +# denotes a block comment, including line 1 and lines 6-9. The string |
| 65 | +# // |
| 66 | +# denotes line 4 as comments. |
| 67 | +# |
| 68 | +# Example 2: |
| 69 | +# Input: |
| 70 | +# source = ["a/*comment", "line", "more_comment*/b"] |
| 71 | +# Output: ["ab"] |
| 72 | +# Explanation: The original source string is "a/*comment\nline\nmore_comment*/b", |
| 73 | +# where we have bolded the newline characters. |
| 74 | +# After deletion, the implicit newline characters are deleted, |
| 75 | +# leaving the string "ab", which when delimited by newline characters becomes ["ab"]. |
| 76 | +# |
| 77 | +# Note: |
| 78 | +# - The length of source is in the range [1, 100]. |
| 79 | +# - The length of source[i] is in the range [0, 80]. |
| 80 | +# - Every open block comment is eventually closed. |
| 81 | +# - There are no single-quote, double-quote, or control characters in the source code. |
| 82 | + |
| 83 | +class Solution(object): |
| 84 | + def removeComments(self, source): |
| 85 | + """ |
| 86 | + :type source: List[str] |
| 87 | + :rtype: List[str] |
| 88 | + """ |
| 89 | + in_block = False |
| 90 | + result = [] |
| 91 | + for line in source: |
| 92 | + i = 0 |
| 93 | + if not in_block: |
| 94 | + newline = [] |
| 95 | + while i < len(line): |
| 96 | + if line[i:i+2] == '/*' and not in_block: |
| 97 | + in_block = True |
| 98 | + i += 1 |
| 99 | + elif line[i:i+2] == '*/' and in_block: |
| 100 | + in_block = False |
| 101 | + i += 1 |
| 102 | + elif not in_block and line[i:i+2] == '//': |
| 103 | + break |
| 104 | + elif not in_block: |
| 105 | + newline.append(line[i]) |
| 106 | + i += 1 |
| 107 | + if newline and not in_block: |
| 108 | + result.append("".join(newline)) |
| 109 | + |
| 110 | + return result |
0 commit comments