xiangpei
2025-05-09 641b4a3b1572f3a75ce0bd7d645e34252237cf9c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package cn.lili.common.sensitive;
 
import java.io.Serializable;
 
/**
 * 字符指针
 *
 * @author Bulbasaur
 * @since 2020-02-25 14:10:16
 */
public class StringPointer implements Serializable, CharSequence, Comparable<StringPointer> {
 
    private static final long serialVersionUID = 1L;
 
    protected final char[] value;
 
    protected final int offset;
 
    protected final int length;
 
    private int hash = 0;
 
    public StringPointer(String str) {
        value = str.toCharArray();
        offset = 0;
        length = value.length;
    }
 
    public StringPointer(char[] value, int offset, int length) {
        this.value = value;
        this.offset = offset;
        this.length = length;
    }
 
 
    /**
     * 计算该位置后(包含)2个字符的hash值
     *
     * @param i 从 0 到 length - 2
     * @return 从 0 到 length - 2
     */
    public int nextTwoCharHash(int i) {
        return 31 * value[offset + i] + value[offset + i + 1];
    }
 
    /**
     * 计算该位置后(包含)2个字符和为1个int型的值<br/>
     * int值相同表示2个字符相同
     *
     * @param i 从 0 到 length - 2
     * @return int值
     */
    public int nextTwoCharMix(int i) {
        return (value[offset + i] << 16) | value[offset + i + 1];
    }
 
    /**
     * 该位置后(包含)的字符串,是否以某个词(word)开头
     *
     * @param i    从 0 到 length - 2
     * @param word 词
     * @return 是否?
     */
    public boolean nextStartsWith(int i, StringPointer word) {
        //是否长度超出
        if (word.length > length - i) {
            return false;
        }
        //从尾开始判断
        for (int c = word.length - 1; c >= 0; c--) {
            if (value[offset + i + c] != word.value[word.offset + c]) {
                return false;
            }
        }
        return true;
    }
 
    /**
     * 填充(替换)
     *
     * @param begin    从此位置开始(含)
     * @param end      到此位置结束(不含)
     * @param fillWith 以此字符填充(替换)
     */
    public void fill(int begin, int end, char fillWith) {
        for (int i = begin; i < end; i++) {
            value[offset + i] = fillWith;
        }
    }
 
    @Override
    public int length() {
        return length;
    }
 
    @Override
    public char charAt(int i) {
        return value[offset + i];
    }
 
    public StringPointer substring(int begin) {
        return new StringPointer(value, offset + begin, length - begin);
    }
 
    public StringPointer substring(int begin, int end) {
        return new StringPointer(value, offset + begin, end - begin);
    }
 
    @Override
    public CharSequence subSequence(int start, int end) {
        return substring(start, end);
    }
 
    @Override
    public String toString() {
        return new String(value, offset, length);
    }
 
    @Override
    public int hashCode() {
        int h = hash;
        if (h == 0 && length > 0) {
            for (int i = 0; i < length; i++) {
                h = 31 * h + value[offset + i];
            }
            hash = h;
        }
        return h;
    }
 
    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof StringPointer) {
            StringPointer that = (StringPointer) anObject;
            if (length == that.length) {
                char[] v1 = this.value;
                char[] v2 = that.value;
                for (int i = 0; i < this.length; i++) {
                    if (v1[this.offset + i] != v2[that.offset + i]) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }
 
    @Override
    public int compareTo(StringPointer that) {
        int len1 = this.length;
        int len2 = that.length;
        int lim = Math.min(len1, len2);
        char[] v1 = this.value;
        char[] v2 = that.value;
 
        int k = 0;
        while (k < lim) {
            char c1 = v1[this.offset + k];
            char c2 = v2[that.offset + k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
 
}