- 浏览: 469812 次
- 性别:
- 来自: 杭州
-
文章分类
- 全部博客 (146)
- Maven (3)
- Quartz (10)
- Hessian (3)
- JDK (42)
- eclipse (4)
- 设计思想 (6)
- XML (8)
- JavaMail (1)
- Spring (11)
- mina (1)
- HsqlDb (1)
- Cache (2)
- Tool (6)
- 心情 (5)
- JQuery (0)
- Hadoop (5)
- Hbase (3)
- 自动构建 (7)
- JNDI (0)
- 代码赏析 (5)
- Oracle (1)
- Excel (4)
- Effective Java (5)
- JAXB (4)
- fdafasdf (1)
- ccc (0)
- web (3)
- concurrent (1)
- CVS (1)
- eclipse plugin (2)
- Apache (10)
最新评论
-
chxiaowu:
nice!
Quartz实现固定执行次数 -
zxjlwt:
学习了。http://surenpi.com
自定义ClassLoader -
kadlly:
public static final Logger log ...
Hessian 权限认证 -
spring_springmvc:
java程序语言学习教程 地址http://www.zuida ...
Java-Final -
liushuiwuyan:
[img][/img]
设计模式-单例
在Java的世界里有个类型叫String,中文名就字符串。
很多时候我们需要使用它来存储, 出了基本的8个类型外,还有Date和String这两个特殊的“基本”类型.
对于字符串,我们接触的多,处理的多,却很少去总结, 比如我们经常把用户信息存储为
USER
id name pass email
1 "abc" "bb" "a@aa.com"
AUTH
id add modify delete
1 true true true
USERAUTH
id userid authid
1 1 1
其实我们还可以这样存储:
SYSTEM
id user auth
1 "abc","bb","a@aa.com" true,true,true
问题就来了, 我们会想这样存储读取和保存不是很麻烦, 还有每一个的字段定义都没有。
其实我想说,要啥字段定义,你Java中定义的对象就是字段定义,你可以随意添加和修改,而不需要修改数据库定义。
问题又来了,那我数据库管理员可不知道你Java怎么定义的,现在要为用户A添加add操作怎么办, 好吧再添加一张数据定义表.
DEFINE
id column defnie
1 user name pass email
2 auth add modify delete
然后, 你的java对象根据这个定义生成对象, 那么还有一个问题, 怎么搜索, 怎么删除....
好吧,每一个定义都有其用处,比如这个数据定义适合做计算结果的存储,这样就不需要每个字段的关联,导致效率等的下降,但是也会多出维护成本,比如用户数据的变更等.
我这人呢喜欢瞎扯,回归正题,如何做分词:
Example1, 以逗号分隔:
"a,b,c,d,e"
思路: 循环每一个字符,当字符为分隔符时:
1. any char matched?
2. preserve(保持) token?
当我们输保持token为false, 那么如果分割为空字符串,忽略.
默认两个标识都为false, 当遇到非分隔符时,设置match为true, 遇到分隔符设为false,那么当match为true时,非空, 当match为false时,连续两个分隔符.
这回处理,当最后一个逗号之后的内容,如果都之后有内容,那么lastMatch为false,match为true.
当逗号之后没内容,那么lastMatch为true,match为false,无论有没内容都加.
当遇到分隔符时,start=++i,表明取下一坐标开始, 而下个坐标为分隔符时, 那么i=i,也就是没有取到字符.
这里如果preserveAllTokens为true,那么无论match是否为true,都加.
如果preserveAllTokens为false,那么只有match为true,不是以都好结尾的才加.
可能有人会觉得这个分词太简单了,比如可以用以下代码:
JDK Source code String.split方法就能解决,多简单啊,但是这个方法不会处理最后一个逗号的值,所以自己定制的字符串分割还是很有意义的。
当然JDK Source Code String.split还有一个扩展的方法
limit: 0, will be applied as many times as possible.
limit: 1~n, will be applied as 1~n times.
limint: >n, the array's last entry will contain all input beyond the last matched delimiter.
简单,这个方法会处理最后一个逗号的值,API的扩展方法。
Example:
Output:
但是如果使用我们自己的split方法:
Output:
你喜欢那个API呢, 如果是我,我会选下面这个,因为字符循环,自定义的优势等等。
具体看看JDK的实现的:
this is section of Pattern.split. CASE_INSENSITIVE to match.
default String.split(","), will be ignore the last ",", cause of the construct result, this will be clean the last one of the Array,if the value is "" will be remove.
当然想要添加最后一个也简单,limit = input.length:
Output:
as this, it is the same as the result of
CSVUtil.split("a,,,,,,d,e,", ',', true);
那么你现在会选哪个做字符串分割呢, JDK代码是经过千锤百炼的,所以使用JDK代码更简单,而且更稳定,效率也更高, 真的吗?
有人说功能越简单越好, JDK的字符串功能太强大了, JDK的regex可以查找,匹配, 分割等,而且刚才的limit也不好设置吧, 而且每一次进行字符串分割都需要构建Partern/Matcher...效率肯定没有直接进行字符遍历来的直接。
很多时候我们需要使用它来存储, 出了基本的8个类型外,还有Date和String这两个特殊的“基本”类型.
对于字符串,我们接触的多,处理的多,却很少去总结, 比如我们经常把用户信息存储为
USER
id name pass email
1 "abc" "bb" "a@aa.com"
AUTH
id add modify delete
1 true true true
USERAUTH
id userid authid
1 1 1
其实我们还可以这样存储:
SYSTEM
id user auth
1 "abc","bb","a@aa.com" true,true,true
问题就来了, 我们会想这样存储读取和保存不是很麻烦, 还有每一个的字段定义都没有。
其实我想说,要啥字段定义,你Java中定义的对象就是字段定义,你可以随意添加和修改,而不需要修改数据库定义。
问题又来了,那我数据库管理员可不知道你Java怎么定义的,现在要为用户A添加add操作怎么办, 好吧再添加一张数据定义表.
DEFINE
id column defnie
1 user name pass email
2 auth add modify delete
然后, 你的java对象根据这个定义生成对象, 那么还有一个问题, 怎么搜索, 怎么删除....
好吧,每一个定义都有其用处,比如这个数据定义适合做计算结果的存储,这样就不需要每个字段的关联,导致效率等的下降,但是也会多出维护成本,比如用户数据的变更等.
我这人呢喜欢瞎扯,回归正题,如何做分词:
Example1, 以逗号分隔:
"a,b,c,d,e"
/** * Splits the provided text into an array, separator specified, preserving * all tokens, including empty tokens created by adjacent separators. * * CSVUtil.split(null, *, true) = null * CSVUtil.split("", *, , true) = [] * CSVUtil.split("a.b.c", '.', true) = ["a", "b", "c"] * CSVUtil.split("a...c", '.', true) = ["a", "", "", "c"] * CSVUtil.split("a...c", '.', false) = ["a", "c"] * * @param str * the string to parse * @param separatorChar * the seperator char * @param preserveAllTokens * if true, adjacent separators are treated as empty token * separators * @return the splitted string */ public static String[] split(String str, char separatorChar, boolean preserveAllTokens) { if (str == null) { return null; } int len = str.length(); if (len == 0) { return new String[0]; } List<String> list = new ArrayList<String>(); int i = 0, start = 0; boolean match = false; boolean lastMatch = false; while (i < len) { if (str.charAt(i) == separatorChar) { if (match || preserveAllTokens) { list.add(str.substring(start, i)); match = false; lastMatch = true; } start = ++i; continue; } lastMatch = false; match = true; i++; } if (match || preserveAllTokens && lastMatch) { list.add(str.substring(start, i)); } return list.toArray(new String[list.size()]); }
思路: 循环每一个字符,当字符为分隔符时:
1. any char matched?
2. preserve(保持) token?
当我们输保持token为false, 那么如果分割为空字符串,忽略.
while (i < len) { if (str.charAt(i) == separatorChar) { if (match) { list.add(str.substring(start, i));lastMatch = true; match = false; } start = ++i; continue; } lastMatch = false; match = true; i++; }
默认两个标识都为false, 当遇到非分隔符时,设置match为true, 遇到分隔符设为false,那么当match为true时,非空, 当match为false时,连续两个分隔符.
if (match || preserveAllTokens && lastMatch) { list.add(str.substring(start, i)); }
这回处理,当最后一个逗号之后的内容,如果都之后有内容,那么lastMatch为false,match为true.
当逗号之后没内容,那么lastMatch为true,match为false,无论有没内容都加.
当遇到分隔符时,start=++i,表明取下一坐标开始, 而下个坐标为分隔符时, 那么i=i,也就是没有取到字符.
这里如果preserveAllTokens为true,那么无论match是否为true,都加.
如果preserveAllTokens为false,那么只有match为true,不是以都好结尾的才加.
可能有人会觉得这个分词太简单了,比如可以用以下代码:
String[] cc = "a,b,c,,d,e,f".split(",");
JDK Source code String.split方法就能解决,多简单啊,但是这个方法不会处理最后一个逗号的值,所以自己定制的字符串分割还是很有意义的。
当然JDK Source Code String.split还有一个扩展的方法
String[] cc = "a,b,c,,d,e,f".split(",",7);
* <p> The <tt>limit</tt> parameter controls the number of times the * pattern is applied and therefore affects the length of the resulting * array. If the limit <i>n</i> is greater than zero then the pattern * will be applied at most <i>n</i> - 1 times, the array's * length will be no greater than <i>n</i>, and the array's last entry * will contain all input beyond the last matched delimiter. If <i>n</i> * is non-positive then the pattern will be applied as many times as * possible and the array can have any length. If <i>n</i> is zero then * the pattern will be applied as many times as possible, the array can * have any length, and trailing empty strings will be discarded.
limit: 0, will be applied as many times as possible.
limit: 1~n, will be applied as 1~n times.
limint: >n, the array's last entry will contain all input beyond the last matched delimiter.
简单,这个方法会处理最后一个逗号的值,API的扩展方法。
Example:
String[] dd = "a,,,,,,d,e,".split(","); System.out.println(Arrays.toString(dd)+":"+dd.length); String[] ee = "a,,,,,,d,e,".split(",",8); System.out.println(Arrays.toString(ee)+":"+ee.length); String[] ff = "a,,,,,,d,e,".split(",",10); System.out.println(Arrays.toString(ff)+":"+ff.length);
Output:
[a, , , , , , d, e]:8 [a, , , , , , d, e,]:8 [a, , , , , , d, e, ]:9
但是如果使用我们自己的split方法:
. String[] aa = CSVUtil.split("a,,,,,,d,e,", ',', false); System.out.println(Arrays.toString(aa)+":"+aa.length); String[] bb = CSVUtil.split("a,,,,,,d,e,", ',', true); System.out.println(Arrays.toString(bb)+":"+bb.length);
Output:
[a, d, e]:3 [a, , , , , , d, e, ]:9
你喜欢那个API呢, 如果是我,我会选下面这个,因为字符循环,自定义的优势等等。
具体看看JDK的实现的:
String[] hh = null; String input = "abcddaeaaa"; int limit = 100; int index = 0; boolean matchLimited = limit > 0; ArrayList<String> matchList = new ArrayList<String>(); Pattern pattern = Pattern.compile("A", 2); Matcher m = pattern.matcher(input); while(m.find()) { if (!matchLimited || matchList.size() < limit - 1) { String match = input.subSequence(index, m.start()).toString(); matchList.add(match); index = m.end(); } else if (matchList.size() == limit - 1) { // last one String match = input.subSequence(index, input.length()).toString(); matchList.add(match); index = m.end(); } } // If no match was found, return this if (index == 0) hh= new String[] {input.toString()}; // Add remaining segment if (!matchLimited || matchList.size() < limit) matchList.add(input.subSequence(index, input.length()).toString()); // Construct result int resultSize = matchList.size(); if (limit == 0){ while (resultSize > 0 && matchList.get(resultSize-1).equals("")){ resultSize--; } } String[] result = new String[resultSize]; hh= matchList.subList(0, resultSize).toArray(result); //if limit is 0, then String.split at this step is delete the last "". // so we should be change limit to s.length.
this is section of Pattern.split. CASE_INSENSITIVE to match.
default String.split(","), will be ignore the last ",", cause of the construct result, this will be clean the last one of the Array,if the value is "" will be remove.
当然想要添加最后一个也简单,limit = input.length:
String input1 = "a,,,,,,d,e,"; String[] ii = input1.split(",",input1.length()); System.out.println(Arrays.toString(ii)+":"+ii.length);
Output:
[a, , , , , , d, e, ]:9
as this, it is the same as the result of
CSVUtil.split("a,,,,,,d,e,", ',', true);
那么你现在会选哪个做字符串分割呢, JDK代码是经过千锤百炼的,所以使用JDK代码更简单,而且更稳定,效率也更高, 真的吗?
有人说功能越简单越好, JDK的字符串功能太强大了, JDK的regex可以查找,匹配, 分割等,而且刚才的limit也不好设置吧, 而且每一次进行字符串分割都需要构建Partern/Matcher...效率肯定没有直接进行字符遍历来的直接。
发表评论
-
Java Application Cache
2016-09-27 19:25 891Application Cache is used very ... -
jdk 1.6 新特性,集成Groovy, 性能很差
2014-04-02 14:27 1289性能都是相对的,如果调用量不是很大的话,可以忽略,毕竟使用为主 ... -
Fake Code easy implements
2014-04-01 15:41 1033package org.miniframe.modules ... -
JDK regex 用法及用途
2014-03-31 15:48 1225查找 Boolean flag = pattern.mat ... -
生产者消费者(四)
2014-03-04 12:32 1156需求: 多个生产者不断的生产产品,多个消费者不断的消费产品,仓 ... -
生产者消费者(三)
2014-03-04 10:59 966需求: 多个生产者不断的生产产品,多个消费者不断的消费产品,仓 ... -
生产者消费者(二)
2014-03-03 15:40 700需求: 多个生产者不断的生产产品,多个消费者不断的消费产品,仓 ... -
生产者消费者模式(一)
2014-02-28 14:30 1036需求: 多个生产者不断的生产产品,多个消费者不断的消费产品,仓 ... -
查看Class文件使用的JDK版本
2013-10-30 14:17 1121由于JDK一般是向下兼容的,所以有时候本地的JDK版本比类库的 ... -
Java源代码转码
2012-12-20 17:22 1328现在中国的项目很多,编码无非是UTF-8,GBK,GB2312 ... -
Tomcat集成OSGI,并通过JNDI开放Web调用
2012-12-03 11:22 3148Tomcat集成OSGi,首先要选择OSGI服务器,我这里采用 ... -
JDK的Logging
2012-11-07 15:49 1690jdk自带有一个log日志,对于一般的使用,仅够了. 代码如下 ... -
java.util.*
2012-11-06 14:23 1382java.util 工具包,灰常的有用,有机会一定要研读源码。 ... -
java.util.concurrent.*
2012-11-02 10:38 17821. java.util.concurrent.ArrayBl ... -
java.util.rt.*
2012-10-31 13:51 11201. java.util.HashMap 散列表,主要是以离散 ... -
巧秒设计方法,不返回null
2016-09-27 19:32 743/** * {@inheritDoc} * ... -
java doc 代码文档
2012-07-13 13:58 1338对于代码规范不解释了,网上很多。 在编写代码的时候,有一点灰 ... -
接口与抽象类
2012-07-11 16:53 11281. 接口设计必谨慎,除非业务变更,否则打死不能动接口。[不变 ... -
JVM优化机制好诡异
2012-04-20 08:43 1474long i[] = new long[1000000]; ... -
JVM优化机制好诡异
2016-09-27 19:32 568long i[] = new long[100000 ...
相关推荐
总的来说,Java实现的中文分词SimHash算法结合了Sanford分词库的分词功能和SimHash的相似度检测,为中文文本的相似度分析提供了一种高效且准确的方法。在实际应用中,这种技术广泛应用于搜索引擎的去重、推荐系统、...
总的来说,这个基于Java的中文自动分词项目为开发者和研究者提供了一个实践和学习自然语言处理技术的平台,无论你是想了解分词算法的内部工作原理,还是需要一个现成的分词工具,都能从中受益。通过深入研究源码,...
在Java编程中,比较两个字符串的匹配字数是一项常见的任务,尤其是在文本处理或模式匹配的场景下。以下是一个简单的实现,通过`RangeDifferencer4Bak`类来完成这个功能。这个类有两个主要方法:`getTempModel`和`...
可以先将字符串转化为词频向量,然后使用Java的`java.util.Math.cos()`计算两个向量的夹角余弦值。 4. **Soundex编码**:主要用于音近词的匹配,将单词编码为一种形式,使相同发音的单词具有相同的编码。Java中内置...
分词是将输入字符串拆分成一系列有意义的单元,称为“词”或“标记”。在算式中,这些词可能包括数字、运算符、括号等。例如,字符串 "2 + 3 * 4" 将被拆分为 ["2", "+", "3", "*", "4"]。 3. **语法分析(Parsing...
“Double Levenshtein算法”是Levenshtein距离的一种变体,通常用于计算字符串之间的编辑距离,即需要多少次单字符插入、删除或替换操作才能将一个字符串转换为另一个。在中文地址匹配中,这个算法可以帮助量化两个...
在编程领域,字符串处理是常见的任务之一,而寻找字符串中的最长回文子串是一个经典问题。回文是指正读反读都一样的字符串,比如“上海自来水来自海上”。本篇文章将探讨如何实现寻找一个字符串中最长回文子串的算法...
在 Java 编程中,字符串处理是至关重要的一个部分,因为字符...`StringTokenizer` 类则用于将字符串分解为令牌,方便进行分词操作。从 JDK 1.4 开始,Java 添加了对正则表达式的全面支持,使字符串处理更加灵活和强大。
下面我们将详细讨论如何实现这一功能,以及涉及到的Java字符串处理技术。 首先,我们要创建一个方法,接收一个字符串作为参数,然后进行相应的转换。这个方法的核心在于对字符串的遍历和子字符串的提取。在给出的...
在Java编程语言中,判断一个字符串是否全由中文字符组成是一项常见的任务,特别是在处理文本数据时。这可能涉及到汉字的校验、分词或者字符编码转换等场景。下面我们将详细探讨如何实现这个功能。 首先,我们需要...
【标题】:“计算器(字符串运算)” 在编程领域,实现一个计算器来处理字符串形式的运算表达式是一项常见的任务。这个“计算器(字符串运算)”项目旨在处理用户输入的复杂数学表达式,例如“-(1+(2-3)*4-(3+...
10. **性能优化**:为了实现高效的分词速度,开发者可能会使用缓存技术、字符串池以及Java的并发库进行性能优化。 " spliter "作为压缩包内的文件名,很可能是指分词器的主类或者核心模块,负责将输入的文本进行...
- **性能优化**:由于分词可能涉及大量的字符串操作,关注代码的性能优化,如利用缓存减少重复分词等。 - **异常处理**:处理可能出现的分词错误,如编码问题、非法字符等。 - **扩展功能**:如果需要更高级的功能,...
同时,Java的字符串操作函数,如`substring()`和`indexOf()`,会在分词算法中起到关键作用。 在压缩包中的“FMM”文件可能是实现了FMM算法的Java源代码,可能包括类定义、方法实现以及测试用例。阅读这些代码有助于...
- **StringTokenizer**:Java中的一个实用类,用于将字符串分割成多个子字符串。它使用指定的分隔符来实现这一功能。 - **HashSet** 和 **Vector**:分别用于存储不重复的元素集合以及动态数组。在这里,它们被用来...
- **字符串分词**:对于较小的文本片段,也能直接进行分词处理。 - **扩展性**:用户可以根据需求自定义扩展,比如添加新的词典、调整匹配策略等。 - **API设计**:提供了简单的接口供其他Java程序调用,进行分词...
Java 分词技术是自然语言处理领域中的重要环节,主要用于将连续的文本字符串分割成具有独立意义的词汇单元,便于后续的分析和处理。在Java中,有多种分词策略,如正向最大匹配、逆向最大匹配以及最大频率匹配。下面...
然后,可以通过初始化JiebaSegmenter对象,调用其segList方法对输入的字符串进行分词。同时,根据项目需求,可以调整分词模式,或者自定义词典来提高分词效果。 4. **与Lucene结合**: Lucene是一个强大的全文搜索...
#### 三、字符串分词器(StringTokenizer) `java.util.StringTokenizer`类用于将字符串分割成多个子字符串(令牌)。与`String`类不同,`StringTokenizer`提供了更高级的分词功能,可以基于特定的分隔符进行分割。...
在IT领域,字符串是编程语言中非常基础且重要的数据类型,用于存储和处理文本信息。在许多编程任务中,我们经常需要对字符串进行各种操作,包括查找字符串长度、确定最大和最小长度以及计算平均长度。这里我们将深入...