1. 程式人生 > >領釦(LeetCode)刪除註釋 個人題解

領釦(LeetCode)刪除註釋 個人題解

給一個 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].
  • 每個塊註釋都會被閉合。
  • 給定的原始碼中不會有單引號、雙引號或其他控制字元。

 

題目本身的邏輯很簡單

首先判斷是否出現了“//”或者“/*”,如果出現了“//”則忽略掉當前行“//”後的所有內容。如果遇到的是“/*”則做一個標記,直到遇到“*/”,之間的所有內容全部忽略。

但是自己寫的時候還是出現了許多問題,沒有考慮全上面遇到的情況,導致了錯誤。比如對優先順序的處理不夠正確,沒有對行進行依次操作。

AC的正確程式碼參考了https://blog.csdn.net/w8253497062015/article/details/80732789

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 public class Solution {
 5     public List<String> removeComments(String[] source) {
 6         List<String> ans = new ArrayList<>();
 7         StringBuilder sb=new StringBuilder();
 8         int i=0;    //標記操作的source行數
 9         int j=0;    //標記有效字元開始位置
10         boolean isk=false;
11         while(i<source.length)
12         {
13             if(isk)
14             {
15                 int kend=source[i].indexOf("*/",j);
16                 if(kend==-1)
17                 {
18                     i++;
19                     j=0;
20                 }
21                 else
22                 {
23                     isk=false;
24                     j=kend+2;
25                 }
26             }
27             else
28             {
29                 int hmark=source[i].indexOf("//",j);
30                 int kbegin=source[i].indexOf("/*",j);
31                 if(hmark==-1)
32                     hmark=source[i].length();
33                 if(kbegin==-1)
34                     kbegin=source[i].length();
35                 for(int k=j;k<Math.min(hmark, kbegin);k++)    //從有效位置開始把當前行處理完畢
36                 {
37                     sb.append(source[i].charAt(k));
38                 }
39                 if(hmark<=kbegin)
40                 {
41                     if(sb.length()>0)    //加入有效行
42                     {
43                         ans.add(new String(sb));
44                         sb.setLength(0);
45                     }
46                     i++;
47                     j=0;
48                 }
49                 else
50                 {
51                     isk=true;
52                     j=kbegin+2;
53                 }
54             }    
55         }
56         return ans;
57     }
58 
59 }