`
cjm0000000
  • 浏览: 32170 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java字符串搜索思想(String)

    博客分类:
  • JAVA
阅读更多

今天被问到Java字符串搜索,中午抽空研究了String的源码。

 

int indexOf(String str)

 

核心查找代码:

 

        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;
                }
            }
        }

 

这段代码的简单思想是:从源字符串的索引0开始,按字符查找,直到最大索引max(max=源字符串长度 - 子字符串长度),找到和子串第一个字符(first)匹配的字符,记下索引位置并且存放到变量i中;

 

接下去判断i是否超出max,如果超出,则直接返回-1,查找结束;

 

如果i小于max,则源字符串索引i加1,子字符串索引k也加1,然后比对这两个索引对应的字符:

如果相等,两个字符串的索引再各自加1继续循环;

如果不相等,跳出循环;

 

继续执行下面的代码: 如果j==end意味着子串遍历完了(也就是在源字符串查找到了子串),返回查找到的子串索引,程序结束;

 

如果不满足j==end,则源字符串的索引i++,然后重新执行上面过程,直到源字符串遍历到最大索引max(这中间可能找到子串,提前返回);

 

这种字符串查找的算法谈不上高效,但是对于小字符串来说应该够用了;

 

对于字符串查找场景较多,并且字符串很长的情况(可能需要查找的子串靠近源字符串的后半部分),这个方法可能效率不够高;

 

 接着写 int lastIndexOf(String str),先上源码:

 

        int strLastIndex = targetOffset + targetCount - 1;
        char strLastChar = target[strLastIndex];
        int min = sourceOffset + targetCount - 1;
        int i = min + fromIndex;

        startSearchForLastChar:
        while (true) {
            while (i >= min && source[i] != strLastChar) {
                i--;
            }
            if (i < min) {
                return -1;
            }
            int j = i - 1;
            int start = j - (targetCount - 1);
            int k = strLastIndex - 1;

            while (j > start) {
                if (source[j--] != target[k--]) {
                    i--;
                    continue startSearchForLastChar;
                }
            }
            return start - sourceOffset + 1;
        }
 

 

 

查找的原理大致和indexOf相同,只不过lastIndexOf是从尾部开始查找的,并且中间的一些细节还是和indexOf不同的。

 

上面这段代码的主要意思是:

初始计算部分:

 计算子串的最后一个字符,存入变量strLastChar中;

计算源字符串查找的终点索引,存入变量min;

计算源字符串的查找起点索引,存入变量i;

 

进入第一个while循环:

           while (i >= min && source[i] != strLastChar) {
                i--;
            }

 这段代码是在源字符串找到和子串最后一个字符相等的字符,把他的索引存入变量i(从尾部开始查找)

 

如果索引i小余min,意味着已经不在上面规定的查找范围之内了,直接返回-1;

如果索引i合法,那么确定源字符串的查找范围(起点j=i-1,终点start=起点-子串长度+1)【源码中终点的变量是start,作者觉得这是查找的终点,请注意区分】

确定子串的查找起点k=子串最后一个字符索引-1

用源字符串的索引j处的字符和子串索引k处的字符比较,并且j和k各自减1:

如果字符相等,则继续执行上面的比较,直到索引j递减到j>start(索引j超出了查找的终点start),则跳出循环继续往下执行;

如果字符不相等,则程序跳转到锚点startSearchForLastChar处,按照上面的逻辑继续执行;

 

如果if (source[j--] != target[k--])的比对一直相等,并且把while (j > start)循环执行完了,意味着在源字符串找到了子串(只需要找到第一个就可以了,当然是从末尾开始找的),程序返回子串的索引。

 

对于很长的字符串查找的优化,推荐一篇文章: KMP子字符串查找算法分析与实现

 

全文完。

 

 

 

 

分享到:
评论

相关推荐

    动态规划算法--1-26对应a-z字符串转换

    动态规划算法:从1到26分别对应a-z的每一个字母,输入一串数字的字符串,转换为字母,输出所有可能的字母序列。如123-&gt;abc、lc、aw 本资源是按照二叉树的思想解决该问题。从字符串的头部开始,每次可以取一个或者两...

    Java编程思想–13字符串

    第十三章 字符串13.1 不可变的String13.2 重载“+”与StringBuilder13.2.1 javap反编译13.3 无意识的递归13.4 String常用方法13.5格式化输出13.5.1 printf()13.5.2 System,out.format()13.5.3 Formatter类13.5.4 ...

    String中三种加法的区别

    JAVA的确是一种令程序员陷入两难境地的言语, 确切的说是思想. 它提供了如此丰富的library,让程序员能够很容易的写出功能强大的程序. 同时它也封装了如此多的细节, 让程序员能够轻易的写出很拙略的程序. 它所代表的...

    Java2简明教程

    全书共12章,主要包括:Java 2编程基础、面向对象编程原理、接口、包、字符串类String和StringBuffer、异常处理、输入和输出、多线程、Java小程序、GUI布局管理、对象序列化、内隐类、Adapter类和事件处理等,非常...

    java初学者必看

    5.1.2 String创建字符串常量 5.1.3 StringBuffer创建字符串 5.2 连接字符串 5.2.1 与字符串的连接 5.2.2 与其他数据类型的连接 5.3 String字符串操作 5.3.1 基本操作 5.3.2 比较 5.3.3 转化 5.3.4 查找 ...

    Java学习用例demo

    1、Java语言基础:包括环境搭建、基本数据类型、包装类、变量、常量定义、控制结构、String字符串处理等; 2、Java语言面向对象:面向对象思想、类声明与对象实例化、成员变量、方法重载,封装性以及子类继承与多态...

    ZhuoZhuoCrayon#my-Nodes#1071.字符串的最大公因子1

    返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2.如果ST有公共因子,反向连接等于正向连接求最大公约数public String g

    java 课程 实验

    1. 熟悉Java中的String、StringBuffer、Math、包装器类的使用方法。 2. 使用常用类解决一般性的应用问题。 3. 掌握JavaSE API文档的使用方法。 二、实验内容 1. 编写一个程序,输出一个字符串中的大写英文字母数,...

    Java初学者都必须理解的六大问题

     上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。  至于为什么要把String类设计成不可...

    JAVA基础课程讲义

    字符串(java.lang.String类)的使用 90 字符串相等的判断 92 思考作业 93 上机作业 94 第四章 异常机制 95 导引问题 95 异常(Exception)的概念 96 异常分类 96 Error 97 Error和Exception的区别 97 Exception 97 ...

    Java的六大问题你都懂了吗

    上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。至于为什么要把String类设计成不可变类,...

    Java SE基础.docx

    非常详细的javaSE知识点梳理,涵盖字符串:(String,StringBuffer,StringBuilder)、数组、面向对象思想、可视化(swing)、异常、集合框架、IO、线程、网络协议、xml等,内附有代码讲解

    java基础案例与开发详解案例源码全

    9.1.3 字符串对象修改228 9.1.4 类型转换230 9.2 StringBuffer类的使用231 9.3 StringBuilder类的使用233 9.4 日期类简介234 9.5 Java语言国际化时间获取与计算238 9.6 Random类和Math类240 9.7 本章习题243 第10章 ...

    JNI函数使用

    传递字符串数组 参数传递 JNI调用 代码清单15-10 在Linux平台上调用C函数的例程——Sample3 public class Sample3 { public native String[] stringMethod(String text); public static void main(String[] ...

    (JAVA)BBS论坛设计 内涵代码

    //连接字符串 private Connection conn=null; //数据库连接对象 public Statement sm=null; //数据库语句对象 public void ConnectDB(){ try { Class.forName( driverName); conn = DriverManager.get...

    一个"短小精悍"的 json 解析库Tomjson.zip

    Tomjson,一个"短小精悍"的 json 解析库,tomjson使用Java语言编写,主要作用是把Java对象(JavaBean)序列化为json格式字符串,将json格式字符串序列化为相对应的Java对象(JavaBean)。项目地址:...

    AIC的Java课程1-6章

     能够使用String,StringBuffer,StringBuilder类创建字符串对象和使用其方法,分辨不同类之间的区别。  能够使用Date, Calendar, Locale, DateFormat,NumberFormat类创建、改变和显示日期、数字和货币...

    JAVA实验报告(3).doc

    2、掌握 Java 基本语法,重点是面向对象的思想和语法。 3、掌握控制台下(应用程序)的输入输出方法,作为后续部分实验的基础。 二、实验类型 设计型。 三、实验内容 1、打开实验室计算机上的集成开发环境 Eclipse ...

    整理后java开发全套达内学习笔记(含练习)

    System.out.printf() 可插入带 % 的输入类型,前两种只可以插入转义符, 不能插入 % 的数据或字符串 在 printf 里面,输出有5个部分 %[argument_index$][flags][width][.precision]conversion 以“%”开头,[第几个...

    JAVA实验报告一.docx

    如果出现一大串的字符系列,则表示环境变量设置成功。 JAVA实验报告一全文共10页,当前为第4页。 JAVA实验报告一全文共10页,当前为第4页。 配置成功截图: 图1.1 显示java的版本信息图 简单的程序设计: 题目1:在...

Global site tag (gtag.js) - Google Analytics