zoukankan      html  css  js  c++  java
  • String源码理解之indexOf、lastIndexOf函数

    1前言

    不多说,直接上源码

    2indexOf源码

    我自己的理解,可能表述不清,多看几遍,不行就debug跟一遍代码自然就懂了。
    /**
    * 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. */
            	//找到第一个字符的位置,for循环嵌套while循环直到找到
                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++);
    
                    //如果j=end则说明第一个字符之后的字符也一一相等
                    
                    //否则继续循环找下一个字符
                    if (j == end) {
                        /* Found whole string. */
                        return i - sourceOffset;
                    }
                }
            }
            return -1;
        }
    

    3lastindexOf源码

    /**
    * 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 lastIndexOf(char[] source, int sourceOffset, int sourceCount,
    char[] target, int targetOffset, int targetCount,
    int fromIndex) {
    /

    * Check arguments; return immediately where possible. For
    * consistency, don't check for null str.
    /
    int rightIndex = sourceCount - targetCount;
    if (fromIndex < 0) {
    return -1;
    }
    if (fromIndex > rightIndex) {
    fromIndex = rightIndex;
    }
    /
    Empty string always matches. */
    if (targetCount == 0) {
    return fromIndex;
    }

        int strLastIndex = targetOffset + targetCount - 1;
        char strLastChar = target[strLastIndex];
        int min = sourceOffset + targetCount - 1;
        int i = min + fromIndex;
    
        //一个标记循环,普通的continue直接跳出当前循环
        startSearchForLastChar:
        while (true) {
        	//哈哈哈  为啥这个地方的源码没有注释呢,程序员肯定是第一遍思考indeof的时候也头疼,所以注释辅助思考,遇到lastindexof他自然就不用思考太多,因为与indexof大同小异。
        	//从后往前找,找到最后一个相等的字符
            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;
    
            //循环直到j=start,说明从最后一个字符往前的所有字符都匹配
            while (j > start) {
                if (source[j--] != target[k--]) {
                    i--;
                    continue startSearchForLastChar;
                }
            }
            return start - sourceOffset + 1;
        }
    }
    

    4总结

    亮点:
    1、匹配首个目标字符。for循环中,嵌套while循环,从源字符串中,找到匹配目标字符的位置。
    2、小范围匹配目标字符串。for循环中,嵌套for循环,在[目标字符串]长度范围内,遍历匹配,如果全部匹配,则return。

  • 相关阅读:
    HDU3336 Count the string —— KMP next数组
    CodeForces
    51Nod 1627 瞬间移动 —— 组合数学
    51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
    51Nod 1225 余数之和 —— 分区枚举
    51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP
    51Nod 机器人走方格 V3 —— 卡特兰数、Lucas定理
    51Nod XOR key —— 区间最大异或值 可持久化字典树
    HDU4825 Xor Sum —— Trie树
    51Nod 1515 明辨是非 —— 并查集 + 启发式合并
  • 原文地址:https://www.cnblogs.com/jnnleo/p/13100523.html
Copyright © 2011-2022 走看看