&LeetCode0722& 刪除註釋

題目

給一個 C++ 程序,刪除程序中的註釋。這個程序source是一個數組,其中source[i]表示第i行源碼。 這表示每行源碼由\n分隔。
在 C++ 中有兩種註釋風格,行內註釋和塊註釋。
字符串// 表示行註釋,表示//和其右側的其餘字符應該被忽略。
字符串/* 表示一個塊註釋,它表示直到*/的下一個(非重疊)出現的所有字符都應該被忽略。(閱讀順序爲從左到右)非重疊是指,字符串/*/並沒有結束塊註釋,因爲註釋的結尾與開頭相重疊。
第一個有效註釋優先於其他註釋:如果字符串//出現在塊註釋中會被忽略。 同樣,如果字符串/*出現在行或塊註釋中也會被忽略。
如果一行在刪除註釋之後變爲空字符串,那麼不要輸出該行。即,答案列表中的每個字符串都是非空的。
樣例中沒有控制字符,單引號或雙引號字符。比如,source = "string s = "/* Not a comment. */";" 不會出現在測試樣例裏。(此外,沒有其他內容(如定義或宏)會干擾註釋。)
我們保證每一個塊註釋最終都會被閉合, 所以在行或塊註釋之外的/*總是開始新的註釋。
最後,隱式換行符可以通過塊註釋刪除。 有關詳細信息,請參閱下面的示例。
從源代碼中刪除註釋後,需要以相同的格式返回源代碼。

示例 1:

輸入:
source = ["/*Test program /", “int main()”, "{ ", " // variable declaration ", “int a, b, c;”, "/ This is a test", " multiline ", " comment for “, " testing */”, “a = b + c;”, “}”]
示例代碼可以編排成這樣:
/*Test program /
int main()
{
// variable declaration
int a, b, c;
/
This is a test
multiline
comment for
testing /
a = b + c;
}
輸出: [“int main()”,"{ “,” “,“int a, b, c;”,“a = b + c;”,”}"]
編排後:
int main()
{
int a, b, c;
a = b + c;
}
解釋:
第 1 行和第 6-9 行的字符串 /
表示塊註釋。第 4 行的字符串 // 表示行註釋。

示例 2:

輸入:
source = [“a/comment", “line”, "more_comment/b”]
輸出: [“ab”]
解釋: 原始的 source 字符串是 “a/comment\nline\nmore_comment/b”, 其中我們用粗體顯示了換行符。刪除>註釋後,隱含的換行符被刪除,留下字符串 “ab” 用換行符分隔成數組時就是 [“ab”].

注意:

source的長度範圍爲[1, 100].
source[i]的長度範圍爲[0, 80].
每個塊註釋都會被閉合。
給定的源碼中不會有單引號、雙引號或其他控制字符。

來源:力扣(LeetCode

思路

開始時,可以直接按字符來逐個處理,由於塊註釋是多行註釋,所以一旦之前有了塊註釋的起始符,當前行的處理方式就不同了,所以需要一個變量blocked來記錄當前是否爲塊註釋狀態,初始化爲false;
其次,建立空字符out,用來保存去除註釋後的字符,開始遍歷整個代碼的每一行,遍歷每一行中的每一個字符,若當前字符是最後一個字符,說明不會再有註釋了,將當前字符加入out中,否則取出當前位置和下一個位置的兩個字符,如果其正好是"/*",說明之後的部分都是塊註釋了,我們將blocked賦值爲true,然後指針向後移動一個,明明兩個字符,爲啥只移動一個呢?因爲另一個可以在for循環中的++i移動;
再次,如果當前兩個字符正好是"//",說明當前行之後都是註釋,我們並不care後面有啥,所以可以直接break掉當前行;如果都不是,說明當前字符是代碼,將其加入out中;
最後,來看看blockedtrue的情況,說明之後的內容都是塊註釋的內容,此處唯一關心的是有沒有結束符"*/",所以還是先做判斷,如果當前不是最後一個字符,說明至少還有兩個字符,然後取出兩個字符,如果正好是塊註釋結束符,那麼我們將標識重置爲false,指針要後移動一個。若當前行遍歷完後,如果out不爲空,且blockedfalse,則將out存入結果res中。

C++代碼

class Solution {
public:
    vector<string> removeComments(vector<string>& source) 
    {
        vector<string> res;
        bool blocked = false;
        string out = "";

        for (string line : source)
        {
            for (int i = 0; i < line.size(); ++i)
            {
                if (!blocked)
                {
                    if (i == line.size() - 1)
                        out += line[i];
                    else
                    {
                        string t = line.substr(i, 2);
                        if (t == "/*")
                            blocked = true, ++i;
                        else if (t == "//")
                            break;
                        else
                            out += line[i];                       
                    }
                }
                else
                {
                    if (i < line.size() - 1)
                    {
                        string t = line.substr(i, 2);
                        if (t == "*/")
                            blocked = false, ++i;
                    }
                }
            }
            if (!out.empty() && !blocked)
            {
                res.push_back(out);
                out = "";
            }
        }
        return res;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章