Java 中字符串的子串搜索
基友前两天参加了阿里的实习生面试,问了个问题,就是关于字符串的子串搜索的问题。想想实现方式无非就是两层循环,但是 java 中是有现成实现的,于是我就去查查源码,看看 java 语言怎么实现这个的,发现也就是差不多的意思。
java.lang 包中 String 类 有几个 indexOf() 函数,我要寻找的是 indexOf(String str) 这个的具体实现,发现了
public int indexOf(String str) {
return indexOf(str, 0);
}
然后 F3 继续找,
public int indexOf(String str, int fromIndex) {
return indexOf(value, offset, count, str.value, str.offset, str.count,
fromIndex);
}
这个调用应该就是算法的实现了,继续 F3
/**
* Code shared by String and StringBuffer to do searches. The source is the
* character array being searched, and the target is the string being
* searched for.
*
* @param source
* the characters being searched.
* @param sourceOffset
* offset of the source string.
* @param sourceCount
* count of the source string.
* @param target
* the characters being searched for.
* @param targetOffset
* offset of the target string.
* @param targetCount
* count of the target string.
* @param fromIndex
* the index to begin searching from.
*/
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount, int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
} char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first)
;
} /* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end
&& source[j] == target[k]; j++, k++)
; if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
注意这个函数是静态函数,是String and StringBuffer公用的一个工具方法,具体算法原理代码中很显而易见。
又查阅了一些资料,目前子串搜索的方法有下面几种,
KMP算法, BM算法,Sunday算法
其中无论是简单程度还是效率排序均为下面:
Sunday > BM > KMP
Sunday 算法的核心思想如下(转自百度百科):
图1 Sunday算法不匹配的情况
图2 Sunday算法移动的第1种情况
图3 Sunday算法移动的第2种情况
附一个Sunday算法的 C++ 实现(原文链接:http://hi.baidu.com/azuryy/item/8a50f54a2f8c72e51381dad3)
/* Sunday.h */
class Sunday
{
public:
Sunday();
~Sunday(); public:
int find(const char* pattern, const char* text); private:
void preCompute(const char* pattern); private:
//Let's assume all characters are all ASCII
static const int ASSIZE = 128;
int _td[ASSIZE] ;
int _patLength;
int _textLength;
}; 源文件
/* Sunday.cpp */ Sunday::Sunday()
{
} Sunday::~Sunday()
{
} void Sunday::preCompute(const char* pattern)
{
for(int i = 0; i < ASSIZE; i++ )
_td[i] = _patLength + 1; const char* p;
for ( p = pattern; *p; p++)
_td[*p] = _patLength - (p - pattern);
} int Sunday::find(const char* pattern, const char* text)
{
_patLength = strlen( pattern );
_textLength = strlen( text ); if ( _patLength <= 0 || _textLength <= 0)
return -1; preCompute( pattern ); const char *t, *p, *tx = text; while (tx + _patLength <= text + _textLength)
{
for (p = pattern, t = tx; *p; ++p, ++t)
{
if (*p != *t)
break;
}
if (*p == 0)
return tx-text;
tx += _td[tx[_patLength]];
}
return -1;
} 简单测试下:
int main() {
char* text = "blog.csdn,blog.net";
char* pattern = "csdn,blog" ;
Sunday sunday; printf("The First Occurence at: %d\n",sunday.find(pattern,text)); return 1;
}
注,上述算法中数组_td[],是用于记录 pattern 中每个字符的位置
Java 中字符串的子串搜索的更多相关文章
- 【转】Java中字符串中子串的查找共有四种方法(indexof())
原文网址:http://wfly2004.blog.163.com/blog/static/1176427201032692927349/ Java中字符串中子串的查找共有四种方法,如下:1.int ...
- Java中字符串中子串的查找共有四种方法(indexof())
Java中字符串中子串的查找共有四种方法(indexof()) Java中字符串中子串的查找共有四种方法,如下:1.int indexOf(String str) :返回第一次出现的指定子字符串在此字 ...
- Java中字符串indexof() 的使用方法
Java中字符串中子串的查找共有四种方法(indexof())indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置.如果没有找到子字符串,则返回-1.如果 startind ...
- 三张图彻底了解Java中字符串的不变性
转载: 三张图彻底了解Java中字符串的不变性 定义一个字符串 String s = "abcd"; s中保存了string对象的引用.下面的箭头可以理解为"存储他的引用 ...
- java中字符串的非空判断
问题如下:在java 中 字符串为null 如何判断String str;if(str==null) ??str.equal("null") ?? 答:我觉得应该搞清楚字符串对象和 ...
- java中字符串String 转 int(转)
java中字符串String 转 int String -> int s="12345"; int i; 第一种方法:i=Integer.parseInt(s); 第二种方法 ...
- JAVA中字符串函数subString的用法小结
本篇文章主要是对JAVA中字符串函数subString的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 String str; str=str.substring(int begi ...
- Java中字符串的一些常见方法
1.Java中字符串的一些常见方法 /** * */ package com.you.model; /** * @author Administrator * @date 2014-02-24 */ ...
- Java中字符串string的数据类型
Java中字符串string的数据类型 时间:2017-07-03 08:01:47 YuanMxy 原文:https://blog.csdn.net/YuanMxy/article/details/ ...
随机推荐
- flask开发restful api系列(2)
继续上一章所讲,上一章我们最后面说道,虽然这个是很小的程序,但还有好几个要优化的地方.先复制一下老的view.py代码. # coding:utf-8 from flask import Flask, ...
- 3D打印论坛
3D打印论坛:http://www.3done.cn http://www.03dp.com www.qjxxw.net/ http://www.3ddayin.net http://oa.zol.c ...
- 【转】 boot.img的解包与打包
原文网址:http://blog.csdn.net/wh_19910525/article/details/8200372 Android 产品中,内核格式是Linux标准的zImage,根文件系统采 ...
- wireshark保存部分报文的方法
抓包时采用下列两种命令: tcpdump –s 0 –i eth0 host IP1 and IP2 and port 5060 and 5080 –v –w file1.pcap 与 tcpdump ...
- c#秒转时分秒
2个办法 @{ int hour = item.track / 3600; int min = (item.track - hour * 3 ...
- 【hihoCoder第十五周】最近公共祖先·二
老实说我没有读题,看见标题直接就写了,毕竟hiho上面都是裸的算法演练. 大概看了下输入输出,套着bin神的模板,做了个正反map映射,但是怎么都得不了满分.等这周结束后,找高人询问下trick. 若 ...
- QQ能上,但是网页打不开的解决办法
QQ能上,但是网页打不开,解决办法是:netsh winsock reset
- 在ubuntu14.04上部署hadoop2.6.3
一.在Ubuntu下创建hadoop组和hadoop用户 增加hadoop用户组,同时在该组里增加hadoop用户,后续在涉及到hadoop操作时,我们使用该用户. 1.创建hadoop用户组 2.创 ...
- Collections.sort()
Comparator是个接口,可重写compare()及equals()这两个方法,用于比价功能:如果是null的话,就是使用元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f, ...
- jQuery中ready与load事件的区别
1.摘要 大家在编程中使用jQuery还有JS的时候一定会在使用之前这样: //document ready $(document).ready(function(){ ...code... }) / ...