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