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/ ...
随机推荐
- unresolved import 解决办法
安装paramiko 需要先安装另两个模块 安装时未注意32bit,安装了64的,本地python是32的所以出错,重装后报错unresolved import,环境是eclipse(pydev) 用 ...
- 原生js和jquery实现图片轮播特效
本文给大家分享的是使用原生JS和JQ两种方法分别实现相同的图片轮播特效,十分的实用,也非常方便大家对比学习原生js和jQuery,有需要的小伙伴可以参考下. 1)首先是页面的结构部分对于我这种左右切换 ...
- Codeforces 527D Clique Problem
http://codeforces.com/problemset/problem/527/D 题意:给出一些点的xi和wi,当|xi−xj|≥wi+wj的时候,两点间存在一条边,找出一个最大的集合,集 ...
- 自制单片机之十三……时钟IC_DS1302
在网上看了很久,发现初学者最有兴趣的就是DS1302时钟电路,也很自然,它是个做出来就让你觉得最实用的电路了,但实际上制做上并不简单,首先你要让你的显示部分(不管是数码管还是LCD)调试通过.然后把D ...
- Qt Lite
http://blog.qt.io/blog/2016/08/18/introducing-the-qt-lite-project-qt-for-any-platform-any-thing-any- ...
- 教程:30分钟学会Adobe Premiere
原文地址:http://tieba.baidu.com/p/2785313831 视频教程地址
- iOS7 UI适配教程
最近写了点iOS7适配的文章,请指正 ios6to7 1 ios6to7 2
- js如何获取object类型里的键值
最近遇到一个问题: var obj = {"name1":"张三","name2":"李四"}; var key = & ...
- #python基础学习模块:marshal 对象的序列化
#标准库地址:https://docs.python.org/2/library/marshal.html"""有时候,要把内存中一个对象持久化保存磁盘或者序列化二进制流 ...
- 事关Animation Tree的工作随笔(二)
上回说到,游戏项目中客观会遇到逻辑状态的复杂性和动画状态的单一性之间的矛盾,那么Animation Tree是如何解决这个问题的呢? 这又需要引入一个定律:就是逻辑状态无论有多么复杂,但一套逻辑状态组 ...