本文的目的在于探讨算法,纯属娱乐和活跃脑细胞。所以,不对删除注释的目的进行讨论:)这是曾经遇到的一道面试题,可惜当时对于题目的理解不到位,导致最后的解法有误。最近有空,静下心来仔细思考了一下,将解法通过BLOG记录下来。
首先,分析一下Java中注释的类型:
/*type1*/
/*
*type2
*/
//type3
实际上,type1和type2是同种类型,只是表现上来看,type2中包含了换行符。
最直接的解法,就是记录注释的开始位置,然后等到注释结束时进行删除操作。伪代码如下:
for(输入文本)
if(/*)记录type1类型注释开始位置;
else if(//)记录type2注释开始位置;
else if(*/)根据type1的开始位置,删除注释;
else if(\n)根据type3的开始位置,删除注释;
看起来问题就这么简单地解决了。然而,我们却没有考虑以下特殊情况:
System.out.println("/*In Mark*/");
代码中的字符串中包含了注释是不能删除的,这下问题有些棘手了。需要判断当前进行删除的注视是否位于字符串之中,所以伪代码修改如下:
for(输入文本)
if(/*)
if(引号开始)continue;
else 记录type1类型注释开始位置;
else if(//)
if(引号开始)continue;
else 记录type3注释开始位置;
else if(*/)
根据type1的开始位置,删除注释;
else if(\n)
根据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 = '\n';
//引号
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("\n");
}
String target = content.toString();
System.out.println(delComments(target));
} catch (Exception e) {
}
}
}
还有别的解决方案吗?能否用正则表达式来实现?继续思考中...
分享到:
相关推荐
使用python脚本快速删除java文件中的注释
1、使用MyEclipse清除注释 2、使用项目工程清除注释 3、简单方便操作 4、代码共享 ..
用java编写的代码注释删除小工具,能去文本中掉//和/* */注释。 第一个按钮的功能为去掉文本框1中代码的注释,输出到文本框2. 第二个按钮的功能为批量删除文件中的注释,并输出到当前目录(新文件名为xxx.txt)。但...
java_SQL文件批量删除注释 ,实现自动批量处理Sql脚本中的注释,方便发布您自己的脚本,简单好用。亲测可以用的,谢谢支持。
1.仅支持删除java文件和txt文件;(如果想支持其他格式的文件,请用"."+格式后缀名替换clear_annot类的103行".txt"); 2.仅支持删除以注释开头的行该行前部的注释;(主要是为了删除jd-gui.exe反编译的文件前部的烦人...
本文实例讲述了Python删除Java源文件中全部注释的实现方法。分享给大家供大家参考,具体如下: 同事想删除一个Java项目中的全部注释,让我帮忙想想办法。 没找不到合适工具,就写了这个脚本,遍历指定目录,查找*....
我写的一个能够删除C、C++代码中注释的程序,删除JAVA代码的注释应该也是可以的^_^
删除原程序中的注释,使程序全部成为有用的程序
去掉java源码注释
使用JAVA代码实现zookeeper服务的节点删除功能,代码带有注释简单易懂
对代码工程中的(如java,jsp,c++,xml,html,js,properties,py等类型)文件注释进行过滤删除,以减少代码的占用空间和打包后的大小等。
Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...
Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...
可以清除 /**/ \\ 代码注释风格的代码. 文件类型不限, .h, .cpp, .m, .java都行, 有源码,可以自己修改
代码范例列表 第1章 示例描述:本章演示如何开始使用JDK进行程序的开发。 HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载...
Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...
Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...
红黑树创建,插入,删除操作代码。包括创建,插入操作,删除操作,代码有详细的注释,java代码实现。
代码行统计工具用Java语言实现,可以对C\C++、Java的源代码进行统计,统计结果包括:总行数、空行数、注释行数和代码行数,统计结果可以以表格的形式显示给用户或另存为文件。 一 执行环境: 操作系统:WindowsNT/...