leetcode 删除注释(模拟题) 中等
题目太长了:https://leetcode-cn.com/problems/remove-comments/
简单意思就是:给 vector<string> &source,表示每一行的代码,代码中有 // 注释和 /* */ 的注释,返回删除后的 vector<string>
然后题目保证:
- 每个块注释都会被闭合。
- 给定的源码中不会有单引号、双引号或其他控制字符。
以及注意两个样例:
可以发现,对于块注释,如果 flag 来标记块注释的开始,然后删除中间部分,再遇到 */ 进行 flag 结束。它的合并 (样例 2.),以及如 /* 与 */ 在同一行的情况 比较难处理。
有一个简单一点的方法:
将源代码组织成一个 string,每一行加 '\n' 进行标记,然后利用一个 vector<bool> tag 来标记某个位置是否被删除,最后再根据未被删除的 '\n' 进行拆分。
class Solution { public: vector<string> removeComments(vector<string>& source) { string tmp; for(auto &str : source) { tmp += str; tmp.push_back('\n'); } vector<bool> tag(tmp.size(), false); // false 表示这个位置未被删除 for(int i = 0; i < tmp.size() - 1; ++ i) { if(tmp[i] == '/' && tmp[i + 1] == '/') { int j = i; while(tmp[j] != '\n') { tag[j] = true; ++ j; } i = j; } else if(tmp[i] == '/' && tmp[i + 1] == '*') { // 注意 /*/ 这种情况!! 所以以下 j 从 i + 2 开始 tag[i] = tag[i + 1] = true; int j = i + 2; while(tmp[j] != '*' || tmp[j + 1] != '/') { tag[j] = true; ++ j; } tag[j] = tag[j + 1] = true; i = j + 1; } } vector<string> ret; string str; for(int i = 0; i < tmp.size(); ++ i) { if(tag[i]) continue; if(tmp[i] == '\n') { if(!str.empty()) { ret.emplace_back(std::move(str)); str.clear(); } } else str.push_back(tmp[i]); } return ret; } };