题目
示例
思路
题意 -> 给定一段代码,将代码中的注释删除并返回。
由于注释只有两种类型:
- 字符串// 表示行注释,表示//和其右侧的其余字符应该被忽略。
- 字符串/* 表示一个块注释,它表示直到下一个(非重叠)出现的*/之间的所有字符都应该被忽略。(阅读顺序为从左到右)非重叠是指,字符串/*/并没有结束块注释,因为注释的结尾与开头相重叠。
那么可以直接模拟,逐行分析源代码。每个字符有两种情况,要么在一个注释内要么不在。因此我们用 in_block 变量来标记状态,该变量为 true 表示在注释内,反之则不在。
假设此刻不在注释块内:
- 遇到 ‘/*’,则将状态改为在注释块内,继续遍历后面第三个字符。
- 遇到 ‘//’,则直接忽略该行后面的部分。
- 遇到其他字符,将该字符记录到 new_line 中。 假设此刻在注释块内,遇到 ‘*/’,则将状态改为不在注释块内,继续遍历后面第三个字符。
我们用 new_line 记录新的一行,当遍历到每行的末尾时,如果不在注释块内并且 new_line 不为空,就把它放入答案中。
代码注释超级详细
代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#define MAX_LINE_LEN 80
char ** removeComments(char ** source, int sourceSize, int* returnSize) {
char **res = (char **)calloc(sourceSize, sizeof(char *));//保存有效值
char new_line[sourceSize * 100 + 1];//临时数组
int pos = 0, new_line_pos = 0;
bool in_block = false;
for (int j = 0; j < sourceSize; j++) {//遍历代码
char *line = source[j];//取当前字符串
int line_size = strlen(line);
for (int i = 0; i < line_size; i++) {//枚举每一个字符
if (in_block) {
//判断注释结束位置
if (i + 1 < line_size && line[i] == '*' && line[i + 1] == '/') {
in_block = false;
i++;
}
} else {
//判断注释开始位置
if (i + 1 < line_size && line[i] == '/' && line[i + 1] == '*') {
in_block = true;
i++;
} else if (i + 1 < line_size && line[i] == '/' && line[i + 1] == '/') {
//行注释,直接跳过当前字符串
break;
} else {
//有效代码,记录
new_line[new_line_pos++] = line[i];
}
}
}
//存储有效字符串
if (!in_block && new_line_pos > 0) {
new_line[new_line_pos] = '\0';
res[pos] = (char *)calloc(new_line_pos + 1, sizeof(char));
strcpy(res[pos], new_line);
pos++;
new_line_pos = 0;
}
*returnSize = pos;
}
return res;
}
作者:小迅
链接:https://leetcode.cn/problems/remove-comments/solutions/2370701/mo-ni-zhu-shi-chao-ji-xiang-xi-by-xun-ge-2ovj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。