Javaコードのコメントの削除


本文の目的はアルゴリズムを検討することであり,純粋に娯楽と活発な脳細胞である.だから、注釈を削除する目的について議論しません:)これはかつて出会った面接問題ですが、残念ながら当時は問題に対する理解が不十分で、最後の解法が間違っていました.最近暇があって、心を静めてよく考えて、解法をBLOGで記録しました.
まず、Javaのコメントのタイプを分析します.
/*type1*/

/*
*type2
*/

//type3

 
実際、type 1とtype 2は同じタイプですが、表現的には、type 2に改行文字が含まれています.
最も直接的な解法は,注釈の開始位置を記録し,注釈が終了するまで削除することである.疑似コードは次のとおりです.
for(    )
  if(/*)  type1        ;
 else if(//)  type2      ;
 else if(*/)  type1     ,    ;
 else if(
) type3 , ;

問題はこのように簡単に解決されたように見えます.しかし、私たちは以下の特別な状況を考慮していません.
System.out.println("/*In Mark*/");

コードの文字列にコメントが含まれていると削除できません.この問題は少し厄介です.現在削除されている注視が文字列の中にあるかどうかを判断する必要があるため、擬似コードは以下のように修正されます.
for(    )
 if(/*)
      if(    )continue;
      else   type1        ;
 else if(//)
      if(    )continue;
      else   type3      ;
 else if(*/)
        type1     ,    ;
 else if(
) type3 , ; else if(") if( ) ; else ;

 
 問題は完全に解決しましたか.引用符の中にネストされた引用符がある場合、引用符の開始の判断に影響しますか?
 もちろん、Javaでは、ネストされた引用符はエスケープを導入する必要があります.したがって、引用符を判断する際には、転義の引用符であるか否かを判断し、もしそうであれば引用符に関する処理は行わない.
ここまで分析すると、以下は実装コードです.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

/**
 * @author Insunny
 * 
 */
public class DelCommentsInJava {

	private static final char MARK = '"';

	private static final char SLASH = '/';

	private static final char BACKSLASH = '\\';

	private static final char STAR = '*';

	private static final char NEWLINE = '
'; // private static final int TYPE_MARK = 1; // private static final int TYPE_SLASH = 2; // private static final int TYPE_BACKSLASH = 3; // private static final int TYPE_STAR = 4; // private static final int TYPE_DSLASH = 5; /** * char[] _start _end * * @param _target * @param _start * @param _end * @return */ public static char[] del(char[] _target, int _start, int _end) { char[] tmp = new char[_target.length - (_end - _start + 1)]; System.arraycopy(_target, 0, tmp, 0, _start); System.arraycopy(_target, _end + 1, tmp, _start, _target.length - _end - 1); return tmp; } /** * * * @param _target * @return */ public static String delComments(String _target) { int preType = 0; int mark = -1, cur = -1, token = -1; // char[] input = _target.toCharArray(); for (cur = 0; cur < input.length; cur++) { if (input[cur] == MARK) { // if (preType == TYPE_BACKSLASH) continue; // if (mark > 0) { // mark = -1; } else { mark = cur; } preType = TYPE_MARK; } else if (input[cur] == SLASH) { // if (mark > 0) continue; // *, if (preType == TYPE_STAR) { input = del(input, token, cur); // cur = token - 1; preType = 0; } else if (preType == TYPE_SLASH) { token = cur - 1; preType = TYPE_DSLASH; } else { preType = TYPE_SLASH; } } else if (input[cur] == BACKSLASH) { preType = TYPE_BACKSLASH; } else if (input[cur] == STAR) { // if (mark > 0) continue; // /, if (preType == TYPE_SLASH) { token = cur - 1; } preType = TYPE_STAR; } else if(input[cur] == NEWLINE) { if(preType == TYPE_DSLASH) { input = del(input, token, cur); // cur = token - 1; preType = 0; } } } return new String(input); } /** * @param args */ public static void main(String[] args) { try { File file = new File("./src/Test.java"); BufferedReader reader = new BufferedReader(new FileReader(file)); StringBuilder content = new StringBuilder(); String tmp = null; while ((tmp = reader.readLine()) != null) { content.append(tmp); content.append("
"); } String target = content.toString(); System.out.println(delComments(target)); } catch (Exception e) { } } }

 他に解決策はありますか?正規表現で実現できますか?考え続けて...