美文网首页
数据结构之串

数据结构之串

作者: xufe | 来源:发表于2018-07-04 17:23 被阅读0次

    什么是串?

    其实串就是我们日常所说的字符串,它是一系列结点组成的一个线性表,每一个结点存储一个字符。我们知道C语言里并没有字符串这种数据类型,而是利用字符数组加以特殊处理(末尾加'\0')来表示一个字符串,事实上数据结构里的串就是一个存储了字符的链表,并且封装实现了各种字符串的常用操作。

    关于Java String 的一些问题

        public static void main(String[] args) {
            System.out.println(substring("张三"));
        }
    
        public static String substring(String str){
            //剪切字符串
            str.substring(1, str.length());
            return str;
        }
    

    上图输出结果是什么?
    String StringBuilder StringBuffer 又有什么区别?
    为什么字符串拼接的时候推荐使用StringBuilder?

    不要慌,我们现在来了解数据结构之串

    String、StringBuilder、StringBuffer类源码分析

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

    比较重要的两个部分,String是一个终态类,不允许继承,value字段也是常量,不允许改变,从这一点就已经可以看出我们对字符串的插入、截取等功能其实不是在原有的字符串上操作的。

    比如字符串A+字符串B,用String实现其实是,先创建一个字符串C,然后再吧字符串A和B放到C

    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++) {
            if (source[i] != first) {
                //匹配第一个字符是否相等
                while (++i <= max && source[i] != first);
            }
    
            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) {
                    return i - sourceOffset;
                }
            }
        }
        //不存在返回-1
        return -1;
    }
    

    以上是对indexOf方法做的一些简单说明,解释的话上面注释已经写清楚了

    StringBuilder

    我们进入StringBuilder的继承类AbstractStringBuilder

    abstract class AbstractStringBuilder implements Appendable, CharSequence {
        //跟String不一样的就是这里不是常量的
        char[] value;
        //多了一个count
        int count;
        AbstractStringBuilder() {
        }
    
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
    
        @Override
        public int length() {
          return count;
        }
    

    从上面的代码上,我们可以大致了解到,StringBuilder是由一个非常量字符数组成的
    接下来我们再看看StringBuilder的append方法

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        //获取追加字符的长度
        int len = str.length();
        //确保追加的字符串有足够的空间
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
    
    StringBuffer

    StringBuffer和StringBuilder非常相似,唯一不一样的在于,StringBuffer是线程安全的,因为它每个方法都加了synchronized,比如

    public synchronized int length() {
        return count;
    }
    

    总结

    做Java经常会听说多字符串拼接的时候用StringBuilder能提高效率,从上面的分析可以看出,String进行字符串拼接的时候,首先需要生成一个两个字符串相加之和大小的字符串,然后再把这两个字符串写入的新的字符串中,这种方式的优点是操作简单,但是内存消耗严重,StringBuilder就不一样了,初始化的字符数组是可变的,拼接的时候发现存储空间不够的情况会自动扩容,拼接操作在原有的字符串上进行的。

    字符搜索KMP算法

    S1: A B C D E F A B C
    S2: E F A
    搜索S1中是否包含S2

    朴素匹配算法

    算法复杂度O(n*m)

    KMP算法
    这文章里面已经有比较完全的解答了
    https://segmentfault.com/a/1190000008575379

    总结的一些关键信息
    最核心的其实就是匹配开头的字符串
    next数组存储的其实就是第一个字符开头
    KMP算法的根本其实就是不需要想暴力匹配一样全部回退,只需要回退到跟搜索字符相同开头的字符就可以了

    ABCDABCEABCA
    ABCA

    当我们匹配到了ABC之后,发现D不对,其实这种情况下,不用回退到第一个重新匹配,只要找到刚刚匹配的ABC中找到A开头的开始就可以了,next数组就是帮我们实现这一点的
    算法复杂度O(n+m)

    相关文章

      网友评论

          本文标题:数据结构之串

          本文链接:https://www.haomeiwen.com/subject/vlrjuftx.html