• 【面试题】Java实现String的IndexOf方法


    先说题后感:程序员这一行,很多时候,自驱学习能力是自我成长一个很重要的因素(当然技术最好的学习途径都是通过项目实践去学习、理解、掌握)。而自学方法中,除了看官方文档、技术博客等途径之外,学习源码也是一个很重要很重要的手段,在这方面,自己还需多努力。

    最近有幸参加了某大厂(自己水平不够,不好意思出名字)的一次电话面试,其中一个就是现场编写代码实现JavaStringIndexOf功能。
    当时想法思路是有的,但是突然从电话面试转到现场编程,思维有点懵有点紧张,最后没写出来。后来面试结束后不甘心,自己冷静的思考了下又重新做了这道题目:

    实现方案一如下:

    public static int IndexOf(String src, String dst) throws Exception{
    
       if(null == src || src.length() < 1 || null == dst || dst.length() < 1){
           return -1;
       }
    
       if(dst.length() > src.length()){
           return -1;
       }
       char[] srcArray = src.toCharArray();
       char[] dstArray = dst.toCharArray();
       int srcLen = srcArray.length;
       int dstLen = dstArray.length;
    
       for(int i = 0; i < srcLen; i++){
    
           boolean find = false;
           if(srcArray[i] == dstArray[0] && (i+dstLen <= srcLen)){
    
               int equalCount = 0;
               for (int j = 0; j < dstLen; j++){
                   if(srcArray[i+j] == dstArray[j]){
                       equalCount++;
                   }
               }
    
               if(equalCount == dstLen){
                   find = true;
               }
           }
    
           if(find){
               return i;
           }
       }
    
       return -1;
    }
    

    实现方案二(可能有点投机取巧了,不过相对方案一可能会耗更多的内存空间):

     public static int IndexOfStr(String src, String dst) throws Exception{
    
        if(null == src || src.length() < 1 || null == dst || dst.length() < 1 || src.length() < dst.length()){
            return -1;
        }
    if(src.equals(dst)){
    return 0;
    }
    
        int srcLen = src.length();
        int dstLen = dst.length();
        char[] srcArray = src.toCharArray();
        char[] dstArray = dst.toCharArray();
    
        for (int i = 0; i < srcLen; i++){
            if (srcArray[i] == dstArray[0] && (i + dstLen) <= srcLen){
            	 // 这里的substring是new新的String空间来存储
                String tmpS = src.substring(i, i + dstLen);
                if (tmpS.equals(dst)){
                    return i;
                }
            }
        }
    
        return -1;
    }
    

    感觉这两个实现还是有点麻烦,我们看下String的源码是如何实现的:

    // 1、入口
    public int indexOf(String str) {
        return indexOf(str, 0);
    }
    
    // 2、调用下面的:
    public int indexOf(String str, int fromIndex) {
    	return indexOf(value, 0, value.length,
    	            str.value, 0, str.value.length, fromIndex);
    }
    
    // 3、最终调用:
    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内置的IndexOf方法,是直接对其char[]类型的私有变量value去比较的:

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final char value[];
    	......
    	......
    }
    

    并且String公开的返回char[] 的方法只有toCharArray,所以我们自己实现的话只能是调用这个方法得到字符数组,或者直接通过charAt(int index) 获得当前位置的字符。

    而源码实现更精简的地方就是对于原字符串,在for循环里面先通过while循环一直查找到当前字符跟目标字符串的首个字符相等的位置,再开始逐个比较后面的字符是否都相等。

  • 相关阅读:
    JavaTPoint 移动开发教程【翻译完成】
    JavaTPoint 数据库教程【翻译完成】
    JavaTPoint PHP 中文教程【翻译完成】
    JavaTPoint .NET 中文教程【翻译完成】
    JavaTPoint 大数据和云计算中文教程【翻译完成】
    python基础学习笔记二:字符串相关知识
    python基础学习笔记(一):基本介绍
    python 基础学习三:数据结构对比
    python 基础学习五:关键字
    python基础学习笔记四:PEP8 Python 编码规范
  • 原文地址:https://www.cnblogs.com/xiaocy66/p/10589245.html
Copyright © 2020-2023  润新知