import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
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.
*/
public class Remove_Comments {
public static void main(String[] args) {
Remove_Comments out = new Remove_Comments();
Solution s = out.new Solution();
// String[] input = new String[]{"int main()","{ "," ","int a, b, c;","a = b + c;","}"};
//
// System.out.println(s.removeComments(input));
//
// System.out.println(s.removeComments_ac(input));
String[] input2 = new String[]{"/*Test program */", "int main()", "{ ", " // variable declaration ", "int a, b, c;", "/* This is a test", " multiline ", " comment for ", " testing */", "a = b + c;", "}"};
System.out.println(s.removeComments(input2));
System.out.println(s.removeComments_ac(input2));
}
class Solution {
public List<String> removeComments(String[] source) {
List<String> result = new ArrayList<>();
if (source == null || source.length == 0) {
return result;
}
boolean unclosed = false;
Pattern line = Pattern.compile("\\/\\/");
Pattern blockStart = Pattern.compile("\\/\\*");
Pattern blockEnd = Pattern.compile("\\*\\/");
for (String each: source) {
if (unclosed) { // failed by "/*Test program */", find "/*" and it's always unclosed
continue;
} else if (line.matcher(each).find()) {
continue;
} else if (blockStart.matcher(each).find()) {
unclosed = true;
} else if (blockEnd.matcher(each).find()) {
unclosed = false;
} else {
result.add(each);
}
}
return result;
}
public List<String> removeComments_ac(String[] source) {
List<String> result = new ArrayList();
if (source == null || source.length == 0) {
return result;
}
boolean unclosed = false;
StringBuilder newline = new StringBuilder();
for (String line: source) {
int i = 0;
char[] chars = line.toCharArray();
if (!unclosed) newline = new StringBuilder();
// scan through this line
while (i < line.length()) {
if (!unclosed && i+1 < line.length() && chars[i] == '/' && chars[i+1] == '*') {
unclosed = true;
i++;
} else if (unclosed && i+1 < line.length() && chars[i] == '*' && chars[i+1] == '/') {
unclosed = false;
i++;
} else if (!unclosed && i+1 < line.length() && chars[i] == '/' && chars[i+1] == '/') {
break;
} else if (!unclosed) {
newline.append(chars[i]);
}
i++;
}
if (!unclosed && newline.length() > 0) {
result.add(new String(newline));
}
}
return result;
}
}
}