Description
以字符串数组的形式给出一份C++程序源码,求去除注释后的源码。注释包括//
和/**/
两种形式。
Constraints
- \(1 \le source.length \le 100\)
- \(0 \le source[i].length \le 80\)
Solution
构建出正确的状态机即可。口述让GPT帮画出来了。
+--------+ "//" +--------+
| NORMAL | ------> | LINE |
+--------+ +--------+
| |
"/*" '\n'
| |
v v
+--------+ "*/" +--------+
| BLOCK | ------> | NORMAL |
+--------+ +--------+
- ChatGPT
一个技巧是同时判断两个字符,而不要单字符作为状态。
同时为了代码整洁,加上一个cmp
可对比单个字符或者两个字符。
(其实也整洁不到哪里去。)
之前还写过一份很OOP的多态实现,那叫一个又长又容易错。
对比之下,这一份代码的核心部分就没几行。
Code
class Solution {
public:
vector<string> removeComments(vector<string>& source) {
enum {
NORMAL,
LINE,
BLOCK,
} state {NORMAL};
vector<string> ans;
string tmp;
auto flush = [&] {
if(!tmp.empty()) ans.emplace_back(std::move(tmp));
};
for(auto &line : source) line += '\n';
for(auto &line : source) {
for(int i = 0; i < line.size(); ++i) {
auto cmp = [&]<size_t N>(const char (&cs)[N]) {
if constexpr (N == 2) {
return line[i] == cs[0];
} else {
static_assert(N == 3);
auto a = line[i];
auto b = (a == '\n') ? '\0' : line[i+1];
return tie(a, b) == tie(cs[0], cs[1]);
}
};
if(state == NORMAL) {
if(cmp("//")) state = LINE, i++;
else if(cmp("/*")) state = BLOCK, i++;
else if(cmp("\n")) flush(), i++;
else tmp += line[i];
continue;
}
if(state == LINE) {
if(cmp("\n")) state = NORMAL, flush(), i++;
continue;
}
if(state == BLOCK) {
if(cmp("*/")) state = NORMAL, i++;
continue;
}
}
}
flush();
return ans;
}
};