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;
    }
};

 

posted @ 2021-08-27 00:01  rookie_Acmer  阅读(51)  评论(0)    收藏  举报