pub struct HashedRange<'a, Hasher>where
Hasher: RollingHasher + ?Sized,{
hashed: &'a [Hasher::Hash],
_marker: PhantomData<fn() -> Hasher>,
}Fields§
§hashed: &'a [Hasher::Hash]§_marker: PhantomData<fn() -> Hasher>Implementations§
Source§impl<'a, Hasher> HashedRange<'a, Hasher>where
Hasher: RollingHasher + ?Sized,
impl<'a, Hasher> HashedRange<'a, Hasher>where
Hasher: RollingHasher + ?Sized,
Sourcefn new(hashed: &'a [Hasher::Hash]) -> Self
fn new(hashed: &'a [Hasher::Hash]) -> Self
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 55)
51 pub fn range<R>(&self, range: R) -> HashedRange<'_, Hasher>
52 where
53 R: RangeBounds<usize>,
54 {
55 HashedRange::new(&self.hashed[to_range(range, self.len())])
56 }
57 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
58 where
59 R: RangeBounds<usize>,
60 {
61 self.range(range).hash()
62 }
63}
64
65#[derive(Debug)]
66pub struct HashedRange<'a, Hasher>
67where
68 Hasher: RollingHasher + ?Sized,
69{
70 hashed: &'a [Hasher::Hash],
71 _marker: PhantomData<fn() -> Hasher>,
72}
73
74impl<Hasher> Clone for HashedRange<'_, Hasher>
75where
76 Hasher: RollingHasher + ?Sized,
77{
78 fn clone(&self) -> Self {
79 *self
80 }
81}
82
83impl<Hasher> Copy for HashedRange<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
84
85impl<Hasher> PartialEq for HashedRange<'_, Hasher>
86where
87 Hasher: RollingHasher + ?Sized,
88{
89 fn eq(&self, other: &Self) -> bool {
90 self.hash() == other.hash()
91 }
92}
93
94impl<Hasher> Eq for HashedRange<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
95
96impl<Hasher> PartialOrd for HashedRange<'_, Hasher>
97where
98 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
99{
100 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
101 let n = self.longest_common_prefix(other);
102 match (self.len() > n, other.len() > n) {
103 (true, true) => {
104 let x = self.hash_range(n..=n);
105 let y = other.hash_range(n..=n);
106 x.hash.partial_cmp(&y.hash)
107 }
108 (x, y) => Some(x.cmp(&y)),
109 }
110 }
111}
112
113impl<Hasher> Ord for HashedRange<'_, Hasher>
114where
115 Hasher: RollingHasher<Hash: Ord> + ?Sized,
116{
117 fn cmp(&self, other: &Self) -> Ordering {
118 let n = self.longest_common_prefix(other);
119 match (self.len() > n, other.len() > n) {
120 (true, true) => {
121 let x = self.hash_range(n..=n);
122 let y = other.hash_range(n..=n);
123 x.hash.cmp(&y.hash)
124 }
125 (x, y) => x.cmp(&y),
126 }
127 }
128}
129
130impl<'a, Hasher> HashedRange<'a, Hasher>
131where
132 Hasher: RollingHasher + ?Sized,
133{
134 fn new(hashed: &'a [Hasher::Hash]) -> Self {
135 Self {
136 hashed,
137 _marker: PhantomData,
138 }
139 }
140 pub fn len(&self) -> usize {
141 self.hashed.len() - 1
142 }
143 pub fn is_empty(&self) -> bool {
144 self.len() == 0
145 }
146 pub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>
147 where
148 R: RangeBounds<usize>,
149 {
150 HashedRange::new(&self.hashed[to_range(range, self.len())])
151 }Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 102)
100 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
101 let n = self.longest_common_prefix(other);
102 match (self.len() > n, other.len() > n) {
103 (true, true) => {
104 let x = self.hash_range(n..=n);
105 let y = other.hash_range(n..=n);
106 x.hash.partial_cmp(&y.hash)
107 }
108 (x, y) => Some(x.cmp(&y)),
109 }
110 }
111}
112
113impl<Hasher> Ord for HashedRange<'_, Hasher>
114where
115 Hasher: RollingHasher<Hash: Ord> + ?Sized,
116{
117 fn cmp(&self, other: &Self) -> Ordering {
118 let n = self.longest_common_prefix(other);
119 match (self.len() > n, other.len() > n) {
120 (true, true) => {
121 let x = self.hash_range(n..=n);
122 let y = other.hash_range(n..=n);
123 x.hash.cmp(&y.hash)
124 }
125 (x, y) => x.cmp(&y),
126 }
127 }
128}
129
130impl<'a, Hasher> HashedRange<'a, Hasher>
131where
132 Hasher: RollingHasher + ?Sized,
133{
134 fn new(hashed: &'a [Hasher::Hash]) -> Self {
135 Self {
136 hashed,
137 _marker: PhantomData,
138 }
139 }
140 pub fn len(&self) -> usize {
141 self.hashed.len() - 1
142 }
143 pub fn is_empty(&self) -> bool {
144 self.len() == 0
145 }
146 pub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>
147 where
148 R: RangeBounds<usize>,
149 {
150 HashedRange::new(&self.hashed[to_range(range, self.len())])
151 }
152 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
153 where
154 R: RangeBounds<usize>,
155 {
156 self.range(range).hash()
157 }
158 pub fn hash(&self) -> Hashed<Hasher> {
159 Hasher::hash_substr(self.hashed)
160 }
161 pub fn longest_common_prefix(&self, other: &Self) -> usize {
162 let n = self.len().min(other.len());
163 let mut ok = 0usize;
164 let mut err = n + 1;
165 while ok + 1 < err {
166 let mid = ok.midpoint(err);
167 if self.range(..mid).hash() == other.range(..mid).hash() {
168 ok = mid;
169 } else {
170 err = mid;
171 }
172 }
173 ok
174 }
175 pub fn chainable(self) -> HashedRangeChained<'a, Hasher> {
176 vec![self].into()
177 }
178}
179
180pub struct HashedRangeChained<'a, Hasher>
181where
182 Hasher: RollingHasher + ?Sized,
183{
184 chained: Vec<HashedRange<'a, Hasher>>,
185 _marker: PhantomData<fn() -> Hasher>,
186}
187
188impl<Hasher: Debug> Debug for HashedRangeChained<'_, Hasher>
189where
190 Hasher: RollingHasher<Hash: Debug> + ?Sized,
191{
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 f.debug_struct("HashedRangeChained")
194 .field("chained", &self.chained)
195 .finish()
196 }
197}
198
199impl<Hasher: Default> Default for HashedRangeChained<'_, Hasher>
200where
201 Hasher: RollingHasher,
202{
203 fn default() -> Self {
204 Self {
205 chained: Default::default(),
206 _marker: Default::default(),
207 }
208 }
209}
210
211impl<Hasher: Clone> Clone for HashedRangeChained<'_, Hasher>
212where
213 Hasher: RollingHasher,
214{
215 fn clone(&self) -> Self {
216 Self {
217 chained: self.chained.clone(),
218 _marker: self._marker,
219 }
220 }
221}
222
223impl<Hasher> PartialEq for HashedRangeChained<'_, Hasher>
224where
225 Hasher: RollingHasher + ?Sized,
226{
227 fn eq(&self, other: &Self) -> bool {
228 let mut a = self.chained.iter().cloned();
229 let mut b = other.chained.iter().cloned();
230 macro_rules! next {
231 ($iter:expr) => {
232 loop {
233 if let Some(x) = $iter.next() {
234 if x.len() > 0 {
235 break Some(x);
236 }
237 } else {
238 break None;
239 }
240 }
241 };
242 }
243 let mut x: Option<HashedRange<'_, Hasher>> = None;
244 let mut y: Option<HashedRange<'_, Hasher>> = None;
245 loop {
246 if x.is_none_or(|x| x.is_empty()) {
247 x = next!(a);
248 }
249 if y.is_none_or(|y| y.is_empty()) {
250 y = next!(b);
251 }
252 if let (Some(x), Some(y)) = (&mut x, &mut y) {
253 let k = x.len().min(y.len());
254 if x.range(..k) != y.range(..k) {
255 return false;
256 }
257 *x = x.range(k..);
258 *y = y.range(k..);
259 } else {
260 break x.is_none() == y.is_none();
261 }
262 }
263 }
264}
265
266impl<Hasher> Eq for HashedRangeChained<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
267
268impl<Hasher> PartialOrd for HashedRangeChained<'_, Hasher>
269where
270 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
271{
272 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
273 let mut a = self.chained.iter().cloned();
274 let mut b = other.chained.iter().cloned();
275 macro_rules! next {
276 ($iter:expr) => {
277 loop {
278 if let Some(x) = $iter.next() {
279 if x.len() > 0 {
280 break Some(x);
281 }
282 } else {
283 break None;
284 }
285 }
286 };
287 }
288 let mut x: Option<HashedRange<'_, Hasher>> = None;
289 let mut y: Option<HashedRange<'_, Hasher>> = None;
290 loop {
291 if x.is_none_or(|x| x.is_empty()) {
292 x = next!(a);
293 }
294 if y.is_none_or(|y| y.is_empty()) {
295 y = next!(b);
296 }
297 if let (Some(x), Some(y)) = (&mut x, &mut y) {
298 let k = x.longest_common_prefix(y);
299 if x.len() > k && y.len() > k {
300 let x = x.hash_range(k..=k);
301 let y = y.hash_range(k..=k);
302 break x.hash.partial_cmp(&y.hash);
303 };
304 *x = x.range(k..);
305 *y = y.range(k..);
306 } else {
307 break x.is_some().partial_cmp(&y.is_some());
308 }
309 }
310 }
311}
312
313impl<Hasher> Ord for HashedRangeChained<'_, Hasher>
314where
315 Hasher: RollingHasher<Hash: Ord> + ?Sized,
316{
317 fn cmp(&self, other: &Self) -> Ordering {
318 let mut a = self.chained.iter().cloned();
319 let mut b = other.chained.iter().cloned();
320 macro_rules! next {
321 ($iter:expr) => {
322 loop {
323 if let Some(x) = $iter.next() {
324 if x.len() > 0 {
325 break Some(x);
326 }
327 } else {
328 break None;
329 }
330 }
331 };
332 }
333 let mut x: Option<HashedRange<'_, Hasher>> = None;
334 let mut y: Option<HashedRange<'_, Hasher>> = None;
335 loop {
336 if x.is_none_or(|x| x.is_empty()) {
337 x = next!(a);
338 }
339 if y.is_none_or(|y| y.is_empty()) {
340 y = next!(b);
341 }
342 if let (Some(x), Some(y)) = (&mut x, &mut y) {
343 let k = x.longest_common_prefix(y);
344 if x.len() > k && y.len() > k {
345 let x = x.hash_range(k..=k);
346 let y = y.hash_range(k..=k);
347 break x.hash.cmp(&y.hash);
348 };
349 *x = x.range(k..);
350 *y = y.range(k..);
351 } else {
352 break x.is_some().cmp(&y.is_some());
353 }
354 }
355 }Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 246)
227 fn eq(&self, other: &Self) -> bool {
228 let mut a = self.chained.iter().cloned();
229 let mut b = other.chained.iter().cloned();
230 macro_rules! next {
231 ($iter:expr) => {
232 loop {
233 if let Some(x) = $iter.next() {
234 if x.len() > 0 {
235 break Some(x);
236 }
237 } else {
238 break None;
239 }
240 }
241 };
242 }
243 let mut x: Option<HashedRange<'_, Hasher>> = None;
244 let mut y: Option<HashedRange<'_, Hasher>> = None;
245 loop {
246 if x.is_none_or(|x| x.is_empty()) {
247 x = next!(a);
248 }
249 if y.is_none_or(|y| y.is_empty()) {
250 y = next!(b);
251 }
252 if let (Some(x), Some(y)) = (&mut x, &mut y) {
253 let k = x.len().min(y.len());
254 if x.range(..k) != y.range(..k) {
255 return false;
256 }
257 *x = x.range(k..);
258 *y = y.range(k..);
259 } else {
260 break x.is_none() == y.is_none();
261 }
262 }
263 }
264}
265
266impl<Hasher> Eq for HashedRangeChained<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
267
268impl<Hasher> PartialOrd for HashedRangeChained<'_, Hasher>
269where
270 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
271{
272 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
273 let mut a = self.chained.iter().cloned();
274 let mut b = other.chained.iter().cloned();
275 macro_rules! next {
276 ($iter:expr) => {
277 loop {
278 if let Some(x) = $iter.next() {
279 if x.len() > 0 {
280 break Some(x);
281 }
282 } else {
283 break None;
284 }
285 }
286 };
287 }
288 let mut x: Option<HashedRange<'_, Hasher>> = None;
289 let mut y: Option<HashedRange<'_, Hasher>> = None;
290 loop {
291 if x.is_none_or(|x| x.is_empty()) {
292 x = next!(a);
293 }
294 if y.is_none_or(|y| y.is_empty()) {
295 y = next!(b);
296 }
297 if let (Some(x), Some(y)) = (&mut x, &mut y) {
298 let k = x.longest_common_prefix(y);
299 if x.len() > k && y.len() > k {
300 let x = x.hash_range(k..=k);
301 let y = y.hash_range(k..=k);
302 break x.hash.partial_cmp(&y.hash);
303 };
304 *x = x.range(k..);
305 *y = y.range(k..);
306 } else {
307 break x.is_some().partial_cmp(&y.is_some());
308 }
309 }
310 }
311}
312
313impl<Hasher> Ord for HashedRangeChained<'_, Hasher>
314where
315 Hasher: RollingHasher<Hash: Ord> + ?Sized,
316{
317 fn cmp(&self, other: &Self) -> Ordering {
318 let mut a = self.chained.iter().cloned();
319 let mut b = other.chained.iter().cloned();
320 macro_rules! next {
321 ($iter:expr) => {
322 loop {
323 if let Some(x) = $iter.next() {
324 if x.len() > 0 {
325 break Some(x);
326 }
327 } else {
328 break None;
329 }
330 }
331 };
332 }
333 let mut x: Option<HashedRange<'_, Hasher>> = None;
334 let mut y: Option<HashedRange<'_, Hasher>> = None;
335 loop {
336 if x.is_none_or(|x| x.is_empty()) {
337 x = next!(a);
338 }
339 if y.is_none_or(|y| y.is_empty()) {
340 y = next!(b);
341 }
342 if let (Some(x), Some(y)) = (&mut x, &mut y) {
343 let k = x.longest_common_prefix(y);
344 if x.len() > k && y.len() > k {
345 let x = x.hash_range(k..=k);
346 let y = y.hash_range(k..=k);
347 break x.hash.cmp(&y.hash);
348 };
349 *x = x.range(k..);
350 *y = y.range(k..);
351 } else {
352 break x.is_some().cmp(&y.is_some());
353 }
354 }
355 }Sourcepub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>where
R: RangeBounds<usize>,
pub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>where
R: RangeBounds<usize>,
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 156)
152 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
153 where
154 R: RangeBounds<usize>,
155 {
156 self.range(range).hash()
157 }
158 pub fn hash(&self) -> Hashed<Hasher> {
159 Hasher::hash_substr(self.hashed)
160 }
161 pub fn longest_common_prefix(&self, other: &Self) -> usize {
162 let n = self.len().min(other.len());
163 let mut ok = 0usize;
164 let mut err = n + 1;
165 while ok + 1 < err {
166 let mid = ok.midpoint(err);
167 if self.range(..mid).hash() == other.range(..mid).hash() {
168 ok = mid;
169 } else {
170 err = mid;
171 }
172 }
173 ok
174 }
175 pub fn chainable(self) -> HashedRangeChained<'a, Hasher> {
176 vec![self].into()
177 }
178}
179
180pub struct HashedRangeChained<'a, Hasher>
181where
182 Hasher: RollingHasher + ?Sized,
183{
184 chained: Vec<HashedRange<'a, Hasher>>,
185 _marker: PhantomData<fn() -> Hasher>,
186}
187
188impl<Hasher: Debug> Debug for HashedRangeChained<'_, Hasher>
189where
190 Hasher: RollingHasher<Hash: Debug> + ?Sized,
191{
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 f.debug_struct("HashedRangeChained")
194 .field("chained", &self.chained)
195 .finish()
196 }
197}
198
199impl<Hasher: Default> Default for HashedRangeChained<'_, Hasher>
200where
201 Hasher: RollingHasher,
202{
203 fn default() -> Self {
204 Self {
205 chained: Default::default(),
206 _marker: Default::default(),
207 }
208 }
209}
210
211impl<Hasher: Clone> Clone for HashedRangeChained<'_, Hasher>
212where
213 Hasher: RollingHasher,
214{
215 fn clone(&self) -> Self {
216 Self {
217 chained: self.chained.clone(),
218 _marker: self._marker,
219 }
220 }
221}
222
223impl<Hasher> PartialEq for HashedRangeChained<'_, Hasher>
224where
225 Hasher: RollingHasher + ?Sized,
226{
227 fn eq(&self, other: &Self) -> bool {
228 let mut a = self.chained.iter().cloned();
229 let mut b = other.chained.iter().cloned();
230 macro_rules! next {
231 ($iter:expr) => {
232 loop {
233 if let Some(x) = $iter.next() {
234 if x.len() > 0 {
235 break Some(x);
236 }
237 } else {
238 break None;
239 }
240 }
241 };
242 }
243 let mut x: Option<HashedRange<'_, Hasher>> = None;
244 let mut y: Option<HashedRange<'_, Hasher>> = None;
245 loop {
246 if x.is_none_or(|x| x.is_empty()) {
247 x = next!(a);
248 }
249 if y.is_none_or(|y| y.is_empty()) {
250 y = next!(b);
251 }
252 if let (Some(x), Some(y)) = (&mut x, &mut y) {
253 let k = x.len().min(y.len());
254 if x.range(..k) != y.range(..k) {
255 return false;
256 }
257 *x = x.range(k..);
258 *y = y.range(k..);
259 } else {
260 break x.is_none() == y.is_none();
261 }
262 }
263 }
264}
265
266impl<Hasher> Eq for HashedRangeChained<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
267
268impl<Hasher> PartialOrd for HashedRangeChained<'_, Hasher>
269where
270 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
271{
272 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
273 let mut a = self.chained.iter().cloned();
274 let mut b = other.chained.iter().cloned();
275 macro_rules! next {
276 ($iter:expr) => {
277 loop {
278 if let Some(x) = $iter.next() {
279 if x.len() > 0 {
280 break Some(x);
281 }
282 } else {
283 break None;
284 }
285 }
286 };
287 }
288 let mut x: Option<HashedRange<'_, Hasher>> = None;
289 let mut y: Option<HashedRange<'_, Hasher>> = None;
290 loop {
291 if x.is_none_or(|x| x.is_empty()) {
292 x = next!(a);
293 }
294 if y.is_none_or(|y| y.is_empty()) {
295 y = next!(b);
296 }
297 if let (Some(x), Some(y)) = (&mut x, &mut y) {
298 let k = x.longest_common_prefix(y);
299 if x.len() > k && y.len() > k {
300 let x = x.hash_range(k..=k);
301 let y = y.hash_range(k..=k);
302 break x.hash.partial_cmp(&y.hash);
303 };
304 *x = x.range(k..);
305 *y = y.range(k..);
306 } else {
307 break x.is_some().partial_cmp(&y.is_some());
308 }
309 }
310 }
311}
312
313impl<Hasher> Ord for HashedRangeChained<'_, Hasher>
314where
315 Hasher: RollingHasher<Hash: Ord> + ?Sized,
316{
317 fn cmp(&self, other: &Self) -> Ordering {
318 let mut a = self.chained.iter().cloned();
319 let mut b = other.chained.iter().cloned();
320 macro_rules! next {
321 ($iter:expr) => {
322 loop {
323 if let Some(x) = $iter.next() {
324 if x.len() > 0 {
325 break Some(x);
326 }
327 } else {
328 break None;
329 }
330 }
331 };
332 }
333 let mut x: Option<HashedRange<'_, Hasher>> = None;
334 let mut y: Option<HashedRange<'_, Hasher>> = None;
335 loop {
336 if x.is_none_or(|x| x.is_empty()) {
337 x = next!(a);
338 }
339 if y.is_none_or(|y| y.is_empty()) {
340 y = next!(b);
341 }
342 if let (Some(x), Some(y)) = (&mut x, &mut y) {
343 let k = x.longest_common_prefix(y);
344 if x.len() > k && y.len() > k {
345 let x = x.hash_range(k..=k);
346 let y = y.hash_range(k..=k);
347 break x.hash.cmp(&y.hash);
348 };
349 *x = x.range(k..);
350 *y = y.range(k..);
351 } else {
352 break x.is_some().cmp(&y.is_some());
353 }
354 }
355 }Sourcepub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>where
R: RangeBounds<usize>,
pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>where
R: RangeBounds<usize>,
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 104)
100 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
101 let n = self.longest_common_prefix(other);
102 match (self.len() > n, other.len() > n) {
103 (true, true) => {
104 let x = self.hash_range(n..=n);
105 let y = other.hash_range(n..=n);
106 x.hash.partial_cmp(&y.hash)
107 }
108 (x, y) => Some(x.cmp(&y)),
109 }
110 }
111}
112
113impl<Hasher> Ord for HashedRange<'_, Hasher>
114where
115 Hasher: RollingHasher<Hash: Ord> + ?Sized,
116{
117 fn cmp(&self, other: &Self) -> Ordering {
118 let n = self.longest_common_prefix(other);
119 match (self.len() > n, other.len() > n) {
120 (true, true) => {
121 let x = self.hash_range(n..=n);
122 let y = other.hash_range(n..=n);
123 x.hash.cmp(&y.hash)
124 }
125 (x, y) => x.cmp(&y),
126 }
127 }
128}
129
130impl<'a, Hasher> HashedRange<'a, Hasher>
131where
132 Hasher: RollingHasher + ?Sized,
133{
134 fn new(hashed: &'a [Hasher::Hash]) -> Self {
135 Self {
136 hashed,
137 _marker: PhantomData,
138 }
139 }
140 pub fn len(&self) -> usize {
141 self.hashed.len() - 1
142 }
143 pub fn is_empty(&self) -> bool {
144 self.len() == 0
145 }
146 pub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>
147 where
148 R: RangeBounds<usize>,
149 {
150 HashedRange::new(&self.hashed[to_range(range, self.len())])
151 }
152 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
153 where
154 R: RangeBounds<usize>,
155 {
156 self.range(range).hash()
157 }
158 pub fn hash(&self) -> Hashed<Hasher> {
159 Hasher::hash_substr(self.hashed)
160 }
161 pub fn longest_common_prefix(&self, other: &Self) -> usize {
162 let n = self.len().min(other.len());
163 let mut ok = 0usize;
164 let mut err = n + 1;
165 while ok + 1 < err {
166 let mid = ok.midpoint(err);
167 if self.range(..mid).hash() == other.range(..mid).hash() {
168 ok = mid;
169 } else {
170 err = mid;
171 }
172 }
173 ok
174 }
175 pub fn chainable(self) -> HashedRangeChained<'a, Hasher> {
176 vec![self].into()
177 }
178}
179
180pub struct HashedRangeChained<'a, Hasher>
181where
182 Hasher: RollingHasher + ?Sized,
183{
184 chained: Vec<HashedRange<'a, Hasher>>,
185 _marker: PhantomData<fn() -> Hasher>,
186}
187
188impl<Hasher: Debug> Debug for HashedRangeChained<'_, Hasher>
189where
190 Hasher: RollingHasher<Hash: Debug> + ?Sized,
191{
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 f.debug_struct("HashedRangeChained")
194 .field("chained", &self.chained)
195 .finish()
196 }
197}
198
199impl<Hasher: Default> Default for HashedRangeChained<'_, Hasher>
200where
201 Hasher: RollingHasher,
202{
203 fn default() -> Self {
204 Self {
205 chained: Default::default(),
206 _marker: Default::default(),
207 }
208 }
209}
210
211impl<Hasher: Clone> Clone for HashedRangeChained<'_, Hasher>
212where
213 Hasher: RollingHasher,
214{
215 fn clone(&self) -> Self {
216 Self {
217 chained: self.chained.clone(),
218 _marker: self._marker,
219 }
220 }
221}
222
223impl<Hasher> PartialEq for HashedRangeChained<'_, Hasher>
224where
225 Hasher: RollingHasher + ?Sized,
226{
227 fn eq(&self, other: &Self) -> bool {
228 let mut a = self.chained.iter().cloned();
229 let mut b = other.chained.iter().cloned();
230 macro_rules! next {
231 ($iter:expr) => {
232 loop {
233 if let Some(x) = $iter.next() {
234 if x.len() > 0 {
235 break Some(x);
236 }
237 } else {
238 break None;
239 }
240 }
241 };
242 }
243 let mut x: Option<HashedRange<'_, Hasher>> = None;
244 let mut y: Option<HashedRange<'_, Hasher>> = None;
245 loop {
246 if x.is_none_or(|x| x.is_empty()) {
247 x = next!(a);
248 }
249 if y.is_none_or(|y| y.is_empty()) {
250 y = next!(b);
251 }
252 if let (Some(x), Some(y)) = (&mut x, &mut y) {
253 let k = x.len().min(y.len());
254 if x.range(..k) != y.range(..k) {
255 return false;
256 }
257 *x = x.range(k..);
258 *y = y.range(k..);
259 } else {
260 break x.is_none() == y.is_none();
261 }
262 }
263 }
264}
265
266impl<Hasher> Eq for HashedRangeChained<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
267
268impl<Hasher> PartialOrd for HashedRangeChained<'_, Hasher>
269where
270 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
271{
272 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
273 let mut a = self.chained.iter().cloned();
274 let mut b = other.chained.iter().cloned();
275 macro_rules! next {
276 ($iter:expr) => {
277 loop {
278 if let Some(x) = $iter.next() {
279 if x.len() > 0 {
280 break Some(x);
281 }
282 } else {
283 break None;
284 }
285 }
286 };
287 }
288 let mut x: Option<HashedRange<'_, Hasher>> = None;
289 let mut y: Option<HashedRange<'_, Hasher>> = None;
290 loop {
291 if x.is_none_or(|x| x.is_empty()) {
292 x = next!(a);
293 }
294 if y.is_none_or(|y| y.is_empty()) {
295 y = next!(b);
296 }
297 if let (Some(x), Some(y)) = (&mut x, &mut y) {
298 let k = x.longest_common_prefix(y);
299 if x.len() > k && y.len() > k {
300 let x = x.hash_range(k..=k);
301 let y = y.hash_range(k..=k);
302 break x.hash.partial_cmp(&y.hash);
303 };
304 *x = x.range(k..);
305 *y = y.range(k..);
306 } else {
307 break x.is_some().partial_cmp(&y.is_some());
308 }
309 }
310 }
311}
312
313impl<Hasher> Ord for HashedRangeChained<'_, Hasher>
314where
315 Hasher: RollingHasher<Hash: Ord> + ?Sized,
316{
317 fn cmp(&self, other: &Self) -> Ordering {
318 let mut a = self.chained.iter().cloned();
319 let mut b = other.chained.iter().cloned();
320 macro_rules! next {
321 ($iter:expr) => {
322 loop {
323 if let Some(x) = $iter.next() {
324 if x.len() > 0 {
325 break Some(x);
326 }
327 } else {
328 break None;
329 }
330 }
331 };
332 }
333 let mut x: Option<HashedRange<'_, Hasher>> = None;
334 let mut y: Option<HashedRange<'_, Hasher>> = None;
335 loop {
336 if x.is_none_or(|x| x.is_empty()) {
337 x = next!(a);
338 }
339 if y.is_none_or(|y| y.is_empty()) {
340 y = next!(b);
341 }
342 if let (Some(x), Some(y)) = (&mut x, &mut y) {
343 let k = x.longest_common_prefix(y);
344 if x.len() > k && y.len() > k {
345 let x = x.hash_range(k..=k);
346 let y = y.hash_range(k..=k);
347 break x.hash.cmp(&y.hash);
348 };
349 *x = x.range(k..);
350 *y = y.range(k..);
351 } else {
352 break x.is_some().cmp(&y.is_some());
353 }
354 }
355 }Sourcepub fn hash(&self) -> Hashed<Hasher>
pub fn hash(&self) -> Hashed<Hasher>
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 61)
57 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
58 where
59 R: RangeBounds<usize>,
60 {
61 self.range(range).hash()
62 }
63}
64
65#[derive(Debug)]
66pub struct HashedRange<'a, Hasher>
67where
68 Hasher: RollingHasher + ?Sized,
69{
70 hashed: &'a [Hasher::Hash],
71 _marker: PhantomData<fn() -> Hasher>,
72}
73
74impl<Hasher> Clone for HashedRange<'_, Hasher>
75where
76 Hasher: RollingHasher + ?Sized,
77{
78 fn clone(&self) -> Self {
79 *self
80 }
81}
82
83impl<Hasher> Copy for HashedRange<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
84
85impl<Hasher> PartialEq for HashedRange<'_, Hasher>
86where
87 Hasher: RollingHasher + ?Sized,
88{
89 fn eq(&self, other: &Self) -> bool {
90 self.hash() == other.hash()
91 }
92}
93
94impl<Hasher> Eq for HashedRange<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
95
96impl<Hasher> PartialOrd for HashedRange<'_, Hasher>
97where
98 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
99{
100 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
101 let n = self.longest_common_prefix(other);
102 match (self.len() > n, other.len() > n) {
103 (true, true) => {
104 let x = self.hash_range(n..=n);
105 let y = other.hash_range(n..=n);
106 x.hash.partial_cmp(&y.hash)
107 }
108 (x, y) => Some(x.cmp(&y)),
109 }
110 }
111}
112
113impl<Hasher> Ord for HashedRange<'_, Hasher>
114where
115 Hasher: RollingHasher<Hash: Ord> + ?Sized,
116{
117 fn cmp(&self, other: &Self) -> Ordering {
118 let n = self.longest_common_prefix(other);
119 match (self.len() > n, other.len() > n) {
120 (true, true) => {
121 let x = self.hash_range(n..=n);
122 let y = other.hash_range(n..=n);
123 x.hash.cmp(&y.hash)
124 }
125 (x, y) => x.cmp(&y),
126 }
127 }
128}
129
130impl<'a, Hasher> HashedRange<'a, Hasher>
131where
132 Hasher: RollingHasher + ?Sized,
133{
134 fn new(hashed: &'a [Hasher::Hash]) -> Self {
135 Self {
136 hashed,
137 _marker: PhantomData,
138 }
139 }
140 pub fn len(&self) -> usize {
141 self.hashed.len() - 1
142 }
143 pub fn is_empty(&self) -> bool {
144 self.len() == 0
145 }
146 pub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>
147 where
148 R: RangeBounds<usize>,
149 {
150 HashedRange::new(&self.hashed[to_range(range, self.len())])
151 }
152 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
153 where
154 R: RangeBounds<usize>,
155 {
156 self.range(range).hash()
157 }
158 pub fn hash(&self) -> Hashed<Hasher> {
159 Hasher::hash_substr(self.hashed)
160 }
161 pub fn longest_common_prefix(&self, other: &Self) -> usize {
162 let n = self.len().min(other.len());
163 let mut ok = 0usize;
164 let mut err = n + 1;
165 while ok + 1 < err {
166 let mid = ok.midpoint(err);
167 if self.range(..mid).hash() == other.range(..mid).hash() {
168 ok = mid;
169 } else {
170 err = mid;
171 }
172 }
173 ok
174 }Sourcepub fn longest_common_prefix(&self, other: &Self) -> usize
pub fn longest_common_prefix(&self, other: &Self) -> usize
Examples found in repository?
crates/competitive/src/string/rolling_hash.rs (line 101)
100 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
101 let n = self.longest_common_prefix(other);
102 match (self.len() > n, other.len() > n) {
103 (true, true) => {
104 let x = self.hash_range(n..=n);
105 let y = other.hash_range(n..=n);
106 x.hash.partial_cmp(&y.hash)
107 }
108 (x, y) => Some(x.cmp(&y)),
109 }
110 }
111}
112
113impl<Hasher> Ord for HashedRange<'_, Hasher>
114where
115 Hasher: RollingHasher<Hash: Ord> + ?Sized,
116{
117 fn cmp(&self, other: &Self) -> Ordering {
118 let n = self.longest_common_prefix(other);
119 match (self.len() > n, other.len() > n) {
120 (true, true) => {
121 let x = self.hash_range(n..=n);
122 let y = other.hash_range(n..=n);
123 x.hash.cmp(&y.hash)
124 }
125 (x, y) => x.cmp(&y),
126 }
127 }
128}
129
130impl<'a, Hasher> HashedRange<'a, Hasher>
131where
132 Hasher: RollingHasher + ?Sized,
133{
134 fn new(hashed: &'a [Hasher::Hash]) -> Self {
135 Self {
136 hashed,
137 _marker: PhantomData,
138 }
139 }
140 pub fn len(&self) -> usize {
141 self.hashed.len() - 1
142 }
143 pub fn is_empty(&self) -> bool {
144 self.len() == 0
145 }
146 pub fn range<R>(&self, range: R) -> HashedRange<'a, Hasher>
147 where
148 R: RangeBounds<usize>,
149 {
150 HashedRange::new(&self.hashed[to_range(range, self.len())])
151 }
152 pub fn hash_range<R>(&self, range: R) -> Hashed<Hasher>
153 where
154 R: RangeBounds<usize>,
155 {
156 self.range(range).hash()
157 }
158 pub fn hash(&self) -> Hashed<Hasher> {
159 Hasher::hash_substr(self.hashed)
160 }
161 pub fn longest_common_prefix(&self, other: &Self) -> usize {
162 let n = self.len().min(other.len());
163 let mut ok = 0usize;
164 let mut err = n + 1;
165 while ok + 1 < err {
166 let mid = ok.midpoint(err);
167 if self.range(..mid).hash() == other.range(..mid).hash() {
168 ok = mid;
169 } else {
170 err = mid;
171 }
172 }
173 ok
174 }
175 pub fn chainable(self) -> HashedRangeChained<'a, Hasher> {
176 vec![self].into()
177 }
178}
179
180pub struct HashedRangeChained<'a, Hasher>
181where
182 Hasher: RollingHasher + ?Sized,
183{
184 chained: Vec<HashedRange<'a, Hasher>>,
185 _marker: PhantomData<fn() -> Hasher>,
186}
187
188impl<Hasher: Debug> Debug for HashedRangeChained<'_, Hasher>
189where
190 Hasher: RollingHasher<Hash: Debug> + ?Sized,
191{
192 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
193 f.debug_struct("HashedRangeChained")
194 .field("chained", &self.chained)
195 .finish()
196 }
197}
198
199impl<Hasher: Default> Default for HashedRangeChained<'_, Hasher>
200where
201 Hasher: RollingHasher,
202{
203 fn default() -> Self {
204 Self {
205 chained: Default::default(),
206 _marker: Default::default(),
207 }
208 }
209}
210
211impl<Hasher: Clone> Clone for HashedRangeChained<'_, Hasher>
212where
213 Hasher: RollingHasher,
214{
215 fn clone(&self) -> Self {
216 Self {
217 chained: self.chained.clone(),
218 _marker: self._marker,
219 }
220 }
221}
222
223impl<Hasher> PartialEq for HashedRangeChained<'_, Hasher>
224where
225 Hasher: RollingHasher + ?Sized,
226{
227 fn eq(&self, other: &Self) -> bool {
228 let mut a = self.chained.iter().cloned();
229 let mut b = other.chained.iter().cloned();
230 macro_rules! next {
231 ($iter:expr) => {
232 loop {
233 if let Some(x) = $iter.next() {
234 if x.len() > 0 {
235 break Some(x);
236 }
237 } else {
238 break None;
239 }
240 }
241 };
242 }
243 let mut x: Option<HashedRange<'_, Hasher>> = None;
244 let mut y: Option<HashedRange<'_, Hasher>> = None;
245 loop {
246 if x.is_none_or(|x| x.is_empty()) {
247 x = next!(a);
248 }
249 if y.is_none_or(|y| y.is_empty()) {
250 y = next!(b);
251 }
252 if let (Some(x), Some(y)) = (&mut x, &mut y) {
253 let k = x.len().min(y.len());
254 if x.range(..k) != y.range(..k) {
255 return false;
256 }
257 *x = x.range(k..);
258 *y = y.range(k..);
259 } else {
260 break x.is_none() == y.is_none();
261 }
262 }
263 }
264}
265
266impl<Hasher> Eq for HashedRangeChained<'_, Hasher> where Hasher: RollingHasher + ?Sized {}
267
268impl<Hasher> PartialOrd for HashedRangeChained<'_, Hasher>
269where
270 Hasher: RollingHasher<Hash: PartialOrd> + ?Sized,
271{
272 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
273 let mut a = self.chained.iter().cloned();
274 let mut b = other.chained.iter().cloned();
275 macro_rules! next {
276 ($iter:expr) => {
277 loop {
278 if let Some(x) = $iter.next() {
279 if x.len() > 0 {
280 break Some(x);
281 }
282 } else {
283 break None;
284 }
285 }
286 };
287 }
288 let mut x: Option<HashedRange<'_, Hasher>> = None;
289 let mut y: Option<HashedRange<'_, Hasher>> = None;
290 loop {
291 if x.is_none_or(|x| x.is_empty()) {
292 x = next!(a);
293 }
294 if y.is_none_or(|y| y.is_empty()) {
295 y = next!(b);
296 }
297 if let (Some(x), Some(y)) = (&mut x, &mut y) {
298 let k = x.longest_common_prefix(y);
299 if x.len() > k && y.len() > k {
300 let x = x.hash_range(k..=k);
301 let y = y.hash_range(k..=k);
302 break x.hash.partial_cmp(&y.hash);
303 };
304 *x = x.range(k..);
305 *y = y.range(k..);
306 } else {
307 break x.is_some().partial_cmp(&y.is_some());
308 }
309 }
310 }
311}
312
313impl<Hasher> Ord for HashedRangeChained<'_, Hasher>
314where
315 Hasher: RollingHasher<Hash: Ord> + ?Sized,
316{
317 fn cmp(&self, other: &Self) -> Ordering {
318 let mut a = self.chained.iter().cloned();
319 let mut b = other.chained.iter().cloned();
320 macro_rules! next {
321 ($iter:expr) => {
322 loop {
323 if let Some(x) = $iter.next() {
324 if x.len() > 0 {
325 break Some(x);
326 }
327 } else {
328 break None;
329 }
330 }
331 };
332 }
333 let mut x: Option<HashedRange<'_, Hasher>> = None;
334 let mut y: Option<HashedRange<'_, Hasher>> = None;
335 loop {
336 if x.is_none_or(|x| x.is_empty()) {
337 x = next!(a);
338 }
339 if y.is_none_or(|y| y.is_empty()) {
340 y = next!(b);
341 }
342 if let (Some(x), Some(y)) = (&mut x, &mut y) {
343 let k = x.longest_common_prefix(y);
344 if x.len() > k && y.len() > k {
345 let x = x.hash_range(k..=k);
346 let y = y.hash_range(k..=k);
347 break x.hash.cmp(&y.hash);
348 };
349 *x = x.range(k..);
350 *y = y.range(k..);
351 } else {
352 break x.is_some().cmp(&y.is_some());
353 }
354 }
355 }More examples
pub fn chainable(self) -> HashedRangeChained<'a, Hasher>
Trait Implementations§
Source§impl<Hasher> Clone for HashedRange<'_, Hasher>where
Hasher: RollingHasher + ?Sized,
impl<Hasher> Clone for HashedRange<'_, Hasher>where
Hasher: RollingHasher + ?Sized,
Source§impl<'a, Hasher> Debug for HashedRange<'a, Hasher>
impl<'a, Hasher> Debug for HashedRange<'a, Hasher>
Source§impl<Hasher> Ord for HashedRange<'_, Hasher>
impl<Hasher> Ord for HashedRange<'_, Hasher>
Source§impl<Hasher> PartialEq for HashedRange<'_, Hasher>where
Hasher: RollingHasher + ?Sized,
impl<Hasher> PartialEq for HashedRange<'_, Hasher>where
Hasher: RollingHasher + ?Sized,
Source§impl<Hasher> PartialOrd for HashedRange<'_, Hasher>
impl<Hasher> PartialOrd for HashedRange<'_, Hasher>
impl<Hasher> Copy for HashedRange<'_, Hasher>where
Hasher: RollingHasher + ?Sized,
impl<Hasher> Eq for HashedRange<'_, Hasher>where
Hasher: RollingHasher + ?Sized,
Auto Trait Implementations§
impl<'a, Hasher> Freeze for HashedRange<'a, Hasher>where
Hasher: ?Sized,
impl<'a, Hasher> RefUnwindSafe for HashedRange<'a, Hasher>
impl<'a, Hasher> Send for HashedRange<'a, Hasher>
impl<'a, Hasher> Sync for HashedRange<'a, Hasher>
impl<'a, Hasher> Unpin for HashedRange<'a, Hasher>where
Hasher: ?Sized,
impl<'a, Hasher> UnwindSafe for HashedRange<'a, Hasher>
Blanket Implementations§
Source§impl<T> AsTotalOrd for Twhere
T: PartialOrd,
impl<T> AsTotalOrd for Twhere
T: PartialOrd,
fn as_total_ord(&self) -> TotalOrd<&T>
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more