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/ ...
随机推荐
- php-fpm:fastcgi_finish_request()
开始研究php-fpm, 在php-fpm的官网上发现一些很有用的功能,记录一下 1.支持php脚本执行慢的log记录 ; The timeout for serving a single reque ...
- DIV 遮挡问题总结
1.DIV被Silverlight遮挡, 加入windowless参数即可. <object id=”silverlight” data=”data:application/x-silverli ...
- Method Swizzling以及AOP编程:在运行时进行代码注入-备用
概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...
- Codeforces 22B Bargaining Table
http://www.codeforces.com/problemset/problem/22/B 题意:求出n*m的方格图中全是0的矩阵的最大周长 思路:枚举 #include<cstdio& ...
- linux文件合并
第一:两个文件的交集,并集前提条件:每个文件中不得有重复行1. 取出两个文件的并集(重复的行只保留一份)2. 取出两个文件的交集(只留下同时存在于两个文件中的文件)3. 删除交集,留下其他的行1. c ...
- POJ 3378
题目链接 查找长度为5的上升序列总数 用的树状数组+高精度 用树状数组求在i前面比i小的数有几个 用的4个树状数组,A[i][j]表示长度为i的以j为结尾的个数,A[i][j]=A[i-1][1... ...
- SQL - 删掉数据库
ALTER DATABASE [DB_NAME]SET OFFLINEWITH ROLLBACK IMMEDIATEGODROP DATABASE [DB_NAME]GO
- Struts分页的一个实现
在Web应用程序里,分页总让我们开发人员感到很头疼,倒不是因为技术上有多么困难,只是本来和业务没有太多关系的这么一个问题,你却得花不少功夫来处理.要是稍不留神,时不时出点问题就更郁闷了.我现在做的一个 ...
- 如何将EXCEL表导入MYSQL
在平时的工作学习中,难免会遇到需要把EXCEL表中的数据导入到MYSQL中,比如要把EXCEL中的数据进行核对,或者要把测试用例导入到TestLink中.本人搜集相关的资料并加以实践总 ...
- js为鼠标添加右击事件
<script language="javascript"> /*document.oncontextmenu=Youji;*/ //为当前文档添加鼠标右击事件,防 ...