深入快出字符串

字符串string:是有零或多个字符组成的有限序列
下面欣赏一首十字回文诗,体会一下字符串的美感

《禅》
空山映雨落花红,
雨落花红乱舞风,
风舞乱红花落雨,
红花落雨映山空。
字符串string:当中的字符数量称为 字符串的长度; 零个字符的字符串称为 空串 null 或 ""都是空字符串
注意空格字符 也是字符 例如:" ";子串:在字符串当中任意连续个数的字符,在主串当中的位置就是第一个字符的index

字符串的比较

思考:数字能通过比较大小,那么字符串怎么比价大小呢?

// 这个是compareTo的源码
public int compareTo(String anotherString) {
    
    
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;

    int k = 0;
    while (k < lim) {
    
    
        char c1 = v1[k];
        char c2 = v2[k];
        // 比较对应位置的字符ASCII码大小
        if (c1 != c2) {
    
    
            return c1 - c2;
        }
        k++;
    }
    // 如果之前每个位都相等 则返回他们字符串长度差
    // 就是其中一个字符串是另一个的子串
    // 返回的正负 按照比较字符串的顺序来的
    // 例如:a.compareTo(b)
    // a<b:return 返回的负数 可能是长度差 或者 最后一个不相等的字符ASCII码值差
    // a==b: return 0
    // a>b: return 返回正数 其中长度差自己其实能看出来
    return len1 - len2;
}

本人也验证了一下:

public static void main(String[] args) {
    
    
    char a = 'e', b='u';
    System.out.println(a-b);
    myStrCompare("she", "shut");
    System.out.println("she".length()-"shell".length());
    myStrCompare("she", "shell");
}

private static void myStrCompare(String a, String b){
    
    
    // 'e'-'u'=-16
    System.out.println(a.compareTo(b));
}
// print result
-16 -16 -2 -2

这些细节面试Java基础的时候 不要只是会用,源码很可能会被问到哦

深入浅出ASCII码

点击了解ASCII的前世今生
点击了解ASCII、Unicode、UTF-8的由来及区别

// 测试demo
char a = 'e', b = 'u';
// 2^31 -1
System.out.println(Integer.MAX_VALUE);
// -2^31
System.out.println(Integer.MIN_VALUE);
// unicode中文编码起步19968, 0x4e00
System.out.println((int)'我');// 25105
System.out.println((int)'爱');// 29233
System.out.println((int)'你');// 20320
System.out.println((int)',');// 65292
System.out.println((int)'嫁');// 23233
System.out.println((int)'给');// 32473
System.out.println((char)25105);// 我
System.out.println((char)19968);// 一 Unicode编码的第一个汉字
System.out.println(a<b);// true

子串的定位问题—串的模式匹配

BM & KMP算法

KMP算法俗称:看毛片算法,真实的是由三位科学家的名字首字母组成 是非常经典的字符串模式匹配算法
减少主串i不必要的回溯,说实话网上一堆的KMP算法的文章 真正写的明白没有几个
今天被领导安排做一些没有任何技术含量的事情 真TM的无语,没办今天的学习量不够 所以回家补一下,真的不容易 程序员这个职业 千万不要去垃圾国企 或 传统行业 没有技术含量 存粹体力活,不吐槽了 回家打开自己的大学开始用到现在的笔记本吧 五年了 依然用的很流畅!!!
子串的迭代j的变化跟主串没啥关系,关键取决于子串的结构 是否有重复值
有点晚 明天接着淦!


为什么能让主串遍历i不回溯 为什么只要考虑子串的结构?

在朴素算法当中主串的i值是不断的回溯的,但是我们研究发现让主串的i值只变大,减少不必要的回溯;
匹配的是子串j值变化 与主串无关 只需要考虑子串的结构重复的问题
对于子串来说 只有相等和不相等 但是主串的不相等时候 却有很多种情况

什么是最长可匹配前缀子串 and 最长可匹配后缀子串?

在一匹配的字符串当中 找出最长前缀和后缀相同的子串;
在下一轮比较,只有前后缀子串重合才有可能出现匹配;

这就是 为什么找到最长可匹配前缀子串和 最长可匹配后缀子串 能够直接移过去!
这又是 为什么KMP算法能够减少主串和子串的回溯的关键!
前缀子串和后缀子串之间不会出现任何与前缀子串重合的可能性,所以直接移过去!

next数组是什么? 手写出来看看?

看完就懂系列

public class KMP implements StringMatcher{
    
    

    @Override
    public int indexOf(String source, String pattern) {
    
    
        return 0;
    }

    private int[] getNext(String p){
    
    
        int[] next = new int[p.length()];
        int i=0,j=0;
        next[0] = 0;
        for (; i < p.length(); i++) {
    
    
            while(j!=0 && p.charAt(j)!=p.charAt(i-1)){
    
    
                next[j] = next[i];
            }
            if (p.charAt(j)==p.charAt(i-1)){
    
    
                j++;
            }
            next[i]=j;
        }
        return next;
    }
}

未完待续!

猜你喜欢

转载自blog.csdn.net/blackxc/article/details/107484989