Streaming Periodicity with Mismatches, Wildcards, and Edits
Abstract
In this work, we study the problem of detecting periodic trends in strings. While detecting exact periodicity has been studied extensively, real-world data is often noisy, where small deviations or mismatches occur between repetitions. This work focuses on a generalized approach to period detection that efficiently handles noise. Given a string of length , the task is to identify integers such that the prefix and the suffix of , each of length , are similar under a given distance measure. Ergün et al. [APPROX-RANDOM 2017] were the first to study this problem in the streaming model under the Hamming distance. In this work, we combine, in a non-trivial way, the Hamming distance sketch of Clifford et al. [SODA 2019] and the structural description of the -mismatch occurrences of a pattern in a text by Charalampopoulos et al. [FOCS 2020] to present a more efficient streaming algorithm for period detection under the Hamming distance. As a corollary, we derive a streaming algorithm for detecting periods of strings which may contain wildcards, a special symbol that match any character of the alphabet. Our algorithm is not only more efficient than that of Ergün et al. [TCS 2020], but it also operates without their assumption that the string must be free of wildcards in its final characters. Additionally, we introduce the first two-pass streaming algorithm for computing periods under the edit distance by leveraging and extending the Bhattacharya–Koucký’s grammar decomposition technique [STOC 2023].
Keywords and phrases:
approximate periods, pattern matching, streaming algorithmsCopyright and License:
2012 ACM Subject Classification:
Theory of computation Pattern matchingFunding:
Partially supported by the grant ANR-20-CE48-0001 from the French National Research Agency (ANR) and a Royal Society International Exchanges Award.Editors:
Ho-Lin Chen, Wing-Kai Hon, and Meng-Tsung TsaiSeries and Publisher:
Leibniz International Proceedings in Informatics, Schloss Dagstuhl – Leibniz-Zentrum für Informatik
1 Introduction
In this work, we consider the problem of computing periodic trends in strings. Informally, a string has period if its prefix of length equals its suffix of length . Alternatively, a string has period if it equals its prefix of length repeated a (possibly, fractional) number of times. The problem of detecting periodic trends in strings has numerous practical applications, including fields like astronomy, financial analytics, and meteorology (see e.g. [11]). The nature and the volume of the data in the applications ask for algorithms able to process the input in very little space and in (almost) real time, such as streaming algorithms. In the streaming setting, we assume that the input string arrives one character at a time and account for all space used, even for the space used to store information about the input data, which results in ultra-efficient algorithms.
The first streaming algorithm for detecting exact periods of a stream of length was given by Ergün, Jowhari, and Sağlam [14], who presented an algorithm with space.111Hereafter, the space is measured in bits.
While the problem of detecting exact periodicity is fundamental to string processing, in practice data is rarely exactly periodic. For example, a string is clearly repetitive, but does not have a small exact period in the sense above. To account for these variations in natural data, Ergün, Jowhari, and Sağlam [14] proposed another streaming algorithm, which allows for approximately computing the Hamming distance (the number of mismatches) between a stream and a string with period , for a given integer . Their algorithm computes the distance with an approximation factor in space . A disadvantage of this algorithm is that must be known in advance, and knowing approximately will not suffice.
Later, Ergün, Grigorescu, Azer, and Zhou [12] suggested a different version of this problem: given a string of length and an integer , they asked for all integer such that the Hamming distance between the string and its copy shifted by is at most (see Section 2 for a definition). They called such -mismatch periods. They proved that for computing all -mismatch periods of a streaming string of length one needs space and that for computing all -mismatch periods in , one needs space. On the other hand, prior work [12, 15] claimed a streaming algorithm that, given a string of length , computes all its -mismatch periods in using only space. However, we found significant gaps in the proof of correctness. Many key arguments are only briefly outlined in both the conference version [12] and the longer arXiv manuscript [15], and as confirmed in private communication with the authors, a full journal version of the paper has not been published. In particular, [15, Theorem 28] is proved only for the case when the string has two distinct -mismatch periods, and is stated to generalize easily to the case when the string has more than two distinct periods. We believe this generalization does not hold; see Appendix A for a detailed explanation.
Finally, in a different work [13] Ergün, Grigorescu, Azer, and Zhou considered the problem of computing periods of incomplete streaming data, where some characters are replaced with wildcards, a special symbol that matches each character of the alphabet. We say that a wildcard-containing string has an integer period if shifted by positions matches itself. They showed that a streaming algorithm which computes all periods of an -length string with wildcards requires space. Conversely, they demonstrated a streaming algorithm which given a string with wildcards computes all its periods under condition that there are no wildcards in the last characters of . The algorithm uses space. They also showed that for , such an algorithm must use space.
Our results
In this work, we continue the study initiated by Ergün, Grigorescu, Azer, and Zhou [12]. We first give a streaming algorithm for computing the -mismatch periods of a string (Theorem 2.10), providing full details and improving over the claimed space bound of Ergün, Grigorescu, Azer, and Zhou [12] by a factor of .
As an almost immediate corollary, and our second contribution, we obtain a similar result for computing periods of a string with few wildcards (Theorem 2.2). Specifically, we both improve the complexity of the algorithm by Ergün, Grigorescu, Azer, and Zhou [13] by a factor of , narrowing the gap between the upper and lower bounds, and remove the assumption that there are no wildcards in the last characters of the input string.
As our third and final contribution, we extend our results to the edit distance. Informally, we say that a string has a -edit period if the edit distance (the number of deletions, insertions, and substitutions required to transform one string into another) between the input string and its copy shifted by characters is at most (see Section 2 for a formal definition). We apply the Bhattacharya–Koucký’s grammar decomposition [4] and then show that we can compute the -edit periods of the input by computing the -mismatch periods of the stream of suitably encoded grammars. As our algorithm for -mismatch periods needs to know the length of the stream (assumption already present in [12]), we make two passes: first, we compute the decomposition and the length of the stream, and in the second pass we compute the periods. As a result, we develop the first two-pass streaming algorithm for computing -edit periods of a string in time and space (Theorem 2.3).222Hereafter, means that we hide factors polylogarithmic in . “Two-pass” means that the algorithm reads as a stream twice. We emphasize that in this work, we deliberately chose to treat our algorithm for -mismatch periods as a black box, using it as a direct application in the context of -edit periods. While it is conceivable that opening this black box and combining its internal components with the Bhattacharya–Koucký technique could lead to a one-pass streaming algorithm for -edit periods, pursuing this direction would require significant new insights. We leave this as a promising open question for future research.
Related work
Other repetitive string structures that have been considered in the literature include palindromes (strings that read the same forward and backwards) and squares (strings equal to two copies of a string concatenated together). Berebrink et al. [3] followed by Gawrychowski et al. [16] studied the question of computing the length of a maximal palindromic substring of a stream that is a palindrome. Merkurev and Shur [21] considered a similar question for squares. Bathie et al. [1] considered the problem of recognising prefixes of a streaming string that are at Hamming (edit) distance at most from palindromes and squares.
2 Results and technical overview
In this work, we assume the word-RAM model of computation and work in a particularly restrictive streaming setting. In this setting, we assume that the input string arrives as a stream, one character at a time. We must account for all the space used, including the space used to store information about the input. Throughout, the space is measured in bits.
Notations and terminology
We assume to be given an alphabet , the elements of which, called characters, can be stored in a single machine word of the word-RAM model. For an integer , we denote the set of all length- strings by , and we set as well as . The empty string is denoted by . For two strings , we use or indifferently to denote their concatenation. For an integer , the string obtained by concatenating to itself times is denoted by ; note that . Furthermore, denotes an infinite string obtained by concatenating infinitely many copies of . For a string and ,333For integers , denote , , and . the th character of is denoted by . We use to denote the length of . For , denotes the substring of if and the empty string otherwise. When or , we omit them, i.e., we write and . We say that a string is a prefix of if there exists such that , and a suffix of if there exists such that . A non-empty string is primitive if implies or .
2.1 -mismatch periods
The Hamming distance between two strings (denoted ) is defined to be equal to infinity if and have different lengths, and otherwise to the number of positions where the two strings differ (mismatches). We define the mismatch information between two length- strings and , as the set . An integer is called a -mismatch period of a string of length if and .
Theorem 2.1 (Informal statement of Theorem 2.10).
Given a string of length and an integer , there is a streaming algorithm that computes all -mismatch periods of in . Furthermore, for each detected -mismatch period , it also returns . The algorithm uses time and space, and is correct w.h.p.444Hereafter, w.h.p. stands for probability at least , for a constant .
To develop our result, we start with a simple idea already present in [12]: If is a -mismatch period of , then for all , the position is a starting position of a -mismatch occurrence of . This already allows to filter out candidate periods. To test whether an integer is a -mismatch period, we check if the Hamming distance between and is at most . For this, we aim to use the Hamming distance sketches introduced by Clifford, Kociumaka, and Porat [9] for strings and . There are two main challenges: First, we might discover a candidate -mismatch period after passing position , which would make it impossible to compute the Hamming distance sketch of due to streaming access limitations. To address this, as in [12], we divide the interval into a logarithmic number of subintervals, filtering positions in each subinterval using progressively shorter prefixes. The second challenge is that the number of candidate periods can be large, and we cannot store all the sketches. Here, we diverge significantly from [12]: To store the sketches in small space, we leverage the concatenability of the Hamming distance sketches of [9] and the structural regularity of -mismatch occurrences as shown by Charalampopoulos, Kociumaka, and Wellnitz [8]. Combining the two ideas together is non-trivial and this is where the main novelty of our result for the Hamming distance is. The proof of Theorem 2.10 is given in Section 3.
Assume to be given a string containing wildcards. By replacing wildcards in a string with a new character, we immediately derive the following:
Theorem 2.2.
Given a string of length containing at most wildcards. There is a streaming algorithm that computes the set of periods of in in time and space. The algorithm is correct w.h.p.
Proof.
If we replace the wildcards in with a new character , then a period of is a -mismatch period of the resulting string in the alphabet , and we can find it via Theorem 2.1. To check that the positions returned by the algorithm are periods of the original string, for each detected -mismatch period, we retrieve the relevant mismatch information and verify that for all mismatching pairs of characters, at least one of those is the special character .
2.2 -edit periods
The edit distance between two strings (denoted by ) is the minimum number of character insertions, deletions, and substitutions required to transform into . We say that an integer is a -edit period of a string of length if and for some , .
Theorem 2.3.
Given a string of length and an integer , there is a two-pass streaming algorithm that computes all -edit periods of in time and space. The algorithm is correct w.h.p.
2.2.1 Preliminaries: Grammar decomposition
We assume familiarity with the notion of straight-line programs (SLP) [18], which represent a subclass of context-free grammars. The size of an SLP is the number of non-terminals and is denoted by . Furthermore, represents a unique string, called the expansion of , . The length of can be computed in time and space [20].
Fact 2.4.
Let and be SLPs representing strings and respectively, and . Both of the following hold:
-
We can compute in time and space (see [5, Proposition 2.1]).
-
Given an integer , we can find all such that and the corresponding edit distances in time and space.
Proof.
By [19] (see also the remark at the end of [10, Section 5]), all such positions can be found in longest common extension (LCE) queries on a string equal to the reverse of . Given two positions , an LCE query asks for the maximal such that . The string can be represented as the expansion of an SLP of size . I [17] showed that after -time and -space preprocessing of the SLP555The result of I [17] gives tighter bounds, but this is sufficient for our purposes, LCE queries on can be answered in time. The claim follows. One of the central tools of our solution is Bhattacharya–Koucký’s grammar decomposition (BK-decomposition) [4]. It is a randomised decomposition that uses as source of randomness two families of hash functions and , where is a suitably chosen parameter. The decomposition of a string is a sequence of SLPs.666Strictly speaking, the decomposition [4] outputs run-length SLPs. However, one can transform those grammars into SLPs with a size blow-up polylogarithmic in [20]. For a sequence of SLPs , define .
Fact 2.5 ([4, Theorem 3.1]).
Let , be the input parameter of the grammar decomposition algorithm, and let . For all large enough, and for with probability .
The BK-decomposition can be maintained in a streaming fashion:
Corollary 2.6 ([6, Lemma 4.2,Theorem 5.1]).
Given a streaming string , there is an algorithm that outputs a stream of SLPs (referred to as definite) and maintains a sequence of SLPs (referred to as active) such that after having read , the concatenation of and equals . The algorithm uses time per character and space (here, we account for all the space used except for the space required to store ). The only operation the algorithm is allowed to perform on is appending a grammar from the right.
We further make use of the following claim:
Corollary 2.7.
Let be integers. Assume , , and . Let and . With probability at least , there exist integers such that each of the following is satisfied (see Figure 1):
-
1.
.
-
2.
and .
-
3.
except for at most indices .
-
4.
equals the sum of , , and .
Bhattacharya and Koucký [4] proved a similar result in the case where and are appended to and , respectively, from the left. By construction, the BK-decomposition is (almost) symmetric, which allows to adapt their argument to show an analogous result for the case where and are appended to and , respectively, from the right. Corollary 2.7 follows by first applying the result of Bhattacharya and Koucký [4] with , and then using our analogous argument with .
Finally, we use the following encoding of SLPs that allows reusing algorithms on strings for sequences of SLPs:
Fact 2.8 ([4, Lemma 3.13]).
Let be a parameter. There is a mapping from the set of SLPs output by the BK-decomposition algorithm to the set of strings of length on an alphabet of size polynomial in (the maximum length of the input string of the BK-decomposition algorithm) that guarantees that the following is satisfied:
-
1.
A grammar can be encoded and decoded in time and space;
-
2.
Encodings of two equal grammars are equal;
-
3.
Encodings of two distinct grammars output by the decomposition algorithm differ in all characters with probability at least .
2.2.2 Proof of Theorem 2.3
A high-level idea of our algorithm is to apply the grammar decomposition to the stream, and then to reduce the problem to the problem of computing periods with mismatches via Corollary 2.7 and ˜2.8. To this end, we need a stronger version of a streaming algorithm for computing periods with mismatches, and in particular, we introduce a weight function on strings. In the case of the Hamming distance, this function is identically zero. In case of the edit distance, we define it as a partial function on , namely, if , then .
Proposition 2.9.
The weight functions defined above satisfy each of the following:
-
For a string of length , can be computed in streaming deterministically using time per character and space;
-
Consider strings . If at least two of are defined, then the third one is defined as well and ;
-
Consider strings that have equal length in . If are defined, then can be computed deterministically in time and space.
For the Hamming distance, and (trivially), and for the edit distance and .
Proof.
The claim is trivial for . In the following, we consider the weight function for the edit distance. First, consider . Its weight can be computed in streaming using time per character, where and space thanks to ˜2.8. The second property obviously holds. Finally, assume and . Let . Given , because of ˜2.8, we have access to all characters in and for . As a result, we can compute in time and space.
In Section 3, we show the following theorem:
Theorem 2.10.
Given a string of length and integers , there is a streaming algorithm that computes all -mismatch periods of in . Furthermore, for each detected -mismatch period , it also returns weight and . The algorithm runs in time, uses space, and is correct w.h.p., where and are as defined in Proposition 2.9.777By taking and , we immediately obtain Theorem 2.1.
Let us now explain how it implies the algorithm for computing -edit periods. Recall that we receive a string of length as a stream. In the first streaming pass on , we apply Corollary 2.6. At every moment of the algorithm, we additionally store the number of definite grammars. By Corollary 2.6, we can then compute in time and space.
In the second streaming pass, we again run the algorithm of Corollary 2.6. When a new character arrives, we update the SLPs and if a SLP becomes definite, i.e. if we append to the stream of definite grammars, we compute in time and space (˜2.8), and feed it character-by-character into the -mismatch period algorithm (Theorem 2.10), where is the parameter from ˜2.8. Consider the moment when we arrive at the end of and let be the active grammars. We compute and feed it by character-by-character into the -mismatch period algorithm. Let be the resulting stream we fed into the algorithm, i.e. , where .
The -mismatch period algorithm retrieves all -mismatch periods of one-by-one. When a -mismatch period is retrieved, we do the following. If is not a multiple of , we discard it immediately. Otherwise, by Corollary 2.7, there are at most values such that . We retrieve the set containing all such from . We finally compute
If , we compute all such that . For all such , we return as a -edit period of .
Correctness.
If is a -edit period of , there exists such that . By Corollary 2.7, there exist integers such that , , and there are at most indices such that and mismatch. By ˜2.8, is a -mismatch period of . Further, :
Claim 2.11.
.
Proof.
We have and hence . Consequently, . Indeed, assume towards a contradiction that . We then have
where the last inequality holds as each SLP , is non-trivial and hence its expansion has length at least one. Finally, since , we obtain and therefore .
Consequently, is detected by the -mismatch period algorithm with . We then identify as a -edit period of by computing the edit distances between the expansions of the mismatching SLPs.
The algorithm fails if Corollary 2.7 fails, or if the -mismatch period algorithm fails, or if ˜2.8 fails, which happens with probability for big enough. Also, notice that when Corollary 2.7 fails, the algorithm computes edit distance that is bigger than the actual distance. As a result, with a standard argument, we can run instances of the algorithm and return the minimal computed distance, to have the algorithm succeed w.h.p.
Complexity.
The first pass on takes time and space. For the second pass, the -mismatch period algorithm takes time and space by Theorem 2.10 and Proposition 2.9. For each -mismatch period returned by the algorithm, we can bound the time needed to compute as follows: Let ). By ˜2.4, we can compute in time , hence if , we can compute in time . If the edit distance computations take total time more than , we can terminate them as we know that .888To be more precise, we upper bound the number of longest common extension queries from 2.4, it should not exceed . Theorem 2.3 follows.
3 Proof of Theorem 2.10
In this section, we prove Theorem 2.10. We first recall essential tools for the Hamming distance, then outline our algorithm and solve each case, and finally analyse it.
3.1 Tools for the Hamming distance
For two strings , a position of is a -mismatch occurrence of in if . For an integer , we define if and otherwise. We denote by the set of -mismatch occurrences of in . For brevity, we define .
Fact 3.1 ([9, Lemmas 6.2-6.4]).
Consider positive integers such that and , and a family of strings. One can assign -bit sketches to all strings so that each of the following holds, assuming that all processed strings belong to :
-
1.
Given sketches , there is an algorithm that uses time to decide whether . If so, is reported.
-
2.
There is an algorithm that constructs one of or given the two other sketches in time.
-
3.
There is an algorithm that constructs or given the other sketch and the integer in time.
-
4.
If , there is an algorithm that constructs from and in time.
All algorithms use space and succeed w.h.p.
Below, we refer to the sketch of ˜3.1 as the -mismatch sketch. Note that for a string and all integer , the sketch includes the sketch (see [9] for a definition). Beyond the properties above, the -mismatch sketch has one additional property:
Corollary 3.2 ([9, Fact 4.4]).
There exists a streaming algorithm that processes a string in space using time per character so that the sketch can be retrieved on demand in time.
By analysing the details of [9, Corollary 3.4], one can derive a streaming algorithm for computing all occurrences of a pattern in a text when the pattern is a prefix of some string and the text is a substring of the same string, which we refer to as the -mismatch algorithm:
Corollary 3.3.
Given a string of length , there is a streaming algorithm for a pattern and a text , where , which uses space and takes time per arriving character. The algorithm reports all positions such that and at the moment of their arrival. For each reported position , and can be reported on demand in time at the moment when arrives. The algorithm is correct w.h.p.
Proof.
Clifford et al. [9, Corollary 3.4] presented an algorithm that reports the endpoints of all -mismatch occurrences of a pattern in a text assuming that it first receives the pattern as a stream and then a text as a stream as well. The algorithm uses space and takes time per arriving character and is correct w.h.p.
This is not the current best algorithm (presented in Clifford et al. [9] as well). The reason why we selected the simpler algorithm is that it allows for the necessary preprocessing of the pattern to be easily done before one needs it for the text processing. Namely, the only information the algorithm stores about the pattern are the -mismatch sketches of the prefixes of the pattern of the lengths equal to powers of two, and the -mismatch sketch of the pattern itself, computed via Corollary 3.2, and the -mismatch sketch of the pattern’s prefix of length is never used before the position of the text.
Fact 3.4 (cf. [8, Theorems 3.1 and 3.2]).
Given a pattern of length , a text of length , and a threshold , at least one of the following holds:
-
1.
The number of -mismatch occurrences of in is bounded by .
-
2.
There is a primitive string of length that satisfies .
In the second case, the difference between the starting positions of any two -mismatch occurrences of in is a multiple of and if is the minimal substring of the text containing all -mismatch occurrences of in , then .
Let be a string of length . For our next lemma, we introduce the forward cyclic rotation . In general, for , a cyclic rotation with shift (resp. ) is obtained by iterating (resp. ) times. Note that a string is primitive if and only if implies .
Lemma 3.5.
Given two strings such that is a prefix of and . Assume that there are primitive strings such that and and such that and . We then have .
Proof.
Suppose towards a contradiction that . By the triangle inequality, we have and . Assume w.l.o.g. .
If there is such that , then by primitivity of , we have , and . Otherwise, for all we have
The last inequality holds because and is primitive. Hence, , and .
3.2 Structure of the algorithm
We can test a position in the following way to decide whether it is a -mismatch period:
Proposition 3.6.
Given , and for an integer , there is an algorithm that can decide whether is a -mismatch period of using time and space. In this case, it also returns . The algorithm is correct w.h.p.
Proof.
First, the algorithm applies ˜3.1 to compute from and in time and space. By ˜3.7, is a -mismatch period of iff . Given and , ˜3.1 allows to decide whether in time and space.
For , our algorithm computes the sketches required by Proposition 3.6 via ˜3.1 and the weights via Proposition 2.9 using total time and space. After reaching the end of , the algorithm tests each of the candidates in total time and space, and for each -mismatch period, returns , , and .
The rest of the section is devoted to computing periods . The following simple observation is crucial for the correctness of our algorithm.
Observation 3.7.
An integer is a -mismatch period of iff . As a corollary, if is a -mismatch period of , then for all , the position is the starting position of a -mismatch occurrence of .
It follows that we can use -mismatch occurrences of appropriately chosen prefixes of in to filter out candidate -mismatch periods. For , define , , and . For each , we give two algorithms run in parallel, which together compute the set of all -mismatch periods of in the interval . The first algorithm assumes that the number of -mismatch occurrences of in is at most (we call such “non-periodic”, slightly abusing the standard definition), while the second one is correct when the number of occurrences is larger than (we call such “periodic”).
3.3 The algorithm for non-periodic
We maintain the sketch and the weight of the current text using Corollary 3.2 and Proposition 2.9 in time per character and space. After reading , we memorise . Additionally, we run the -mismatch algorithm (Corollary 3.3) for a pattern and a text , which in particular computes . Furthermore, we maintain two hash tables, each of size at most , and . Intuitively, we want to contain every position which is the starting position of a -mismatch occurrence of in , associated with and the weight of . As for the table , we would like it to contain every position such that , again associated with and the weight of . We implement and via the cuckoo hashing scheme [22] and de-amortise as explained in [2, Theorem A.1] to yield the following:
Fact 3.8 ([22, 2]).
A set of integers in , where is the size of the machine word, can be stored in space while maintaining look-up queries in worst-case time and insertions in worst-case time w.h.p.
When we receive a character , the tables are updated as follows. Assume first that the -mismatch algorithm detects a new occurrence of ending at the position . We retrieve and in time (˜3.1). Furthermore, with , we can deduce , and finally, with , we compute , and add associated with and to in time and space. Secondly, if for we have , we add associated with to . If either of the two insertions takes more than constant time or if the size of any of and becomes larger than , the algorithm terminates and returns . Assume that the algorithm has reached the end of .
Proposition 3.9.
If , then and .
Proof.
As , by ˜3.7 is the ending position of a -mismatch occurrence of in . Furthermore, , and hence is a fragment of . This proves that . To show that , note that
Therefore, , and will be added to before . The claim follows.
Finally, the algorithm considers each position , extracts from and from and if passes the test of Proposition 3.6, reports as a -mismatch period of , and returns .
Proposition 3.10.
Assume that the number of occurrences of in is at most . The algorithm computes and in time and space and is correct w.h.p.
Proof.
The algorithm runs an instance of the -mismatch algorithm (Corollary 3.3) that takes time and space. Computing weights takes time and space. Adding elements to and , as well as look-ups, takes time per element, and we add at most elements in total. The two hash tables occupy space (˜3.8, ˜3.1). Finally, testing all candidate positions requires time and space (Proposition 3.6). The correctness of the algorithm follows from Proposition 3.9 and Proposition 3.6. The algorithm can fail if the -mismatch algorithm errs, or if adding an element to the hash tables takes more than constant time, or if the test fails. By the union bound, Corollary 3.3, ˜3.1, and Proposition 3.6, the failure probability is inverse-polynomial in .
3.4 The algorithm for periodic
We first explain how we preprocess . Recall the Boyer–Moore majority vote algorithm:
Fact 3.11 ([7]).
Given a sequence of elements, there is a streaming algorithm that stores elements of the sequence and returns a majority element if there exists one (otherwise, it can return an arbitrary element). Assuming constant-time access and comparison on the elements, the algorithm takes time.
Lemma 3.12.
Given a prefix of , there is a streaming algorithm that uses space and runs in time. If there is a primitive string of length that satisfies , the algorithm computes, correctly w.h.p., , , and before or upon the arrival of . If there is no such string, the algorithm determines it before arrives.
Proof.
The main idea of the lemma is that must be the starting position of the first -mismatch occurrence of in . As soon as we know , we compute the -mismatch sketches and the weights of consecutive substrings of length . By ˜3.4, the majority of them equal , which allows computing and via the Boyer–Moore majority vote algorithm [7]. We now provide full details.
For brevity, let . We run the -mismatch algorithm for a pattern and a text . If the -mismatch algorithm does not detect an occurrence of before or when reading the position , the algorithm concludes that does not exist and terminates. Assume now that the algorithm does detect a -mismatch occurrence of the pattern ending at a position , , and let it be the first detected occurrence. The instance of the -mismatch algorithm is immediately terminated and we launch the majority vote algorithm (˜3.11). Let and the smallest multiple of greater than . We then compute , , …, via Corollary 3.2 and feed them into the majority vote algorithm. After all the sketches have been computed, which happens when we read the position , we return and the output of the majority vote algorithm as . Using the same majority vote approach, we compute .
We now show the correctness of the algorithm. We start by showing that if exists, then . Let be a multiple of smaller than . By ˜3.4 and the triangle inequality, we have . Reciprocally, if is not a multiple of , then by primitivity of we have . Furthermore, by the triangle inequality, , which implies . Consequently, if exists, at least of the strings , , …, are equal to , and the majority vote algorithm indeed outputs (assuming that neither the -mismatch algorithm nor the algorithm of Corollary 3.2 did not err, which is true w.h.p.).
We finally analyse the complexity of the preprocessing step. The -mismatch pattern matching algorithm (Corollary 3.3) takes time per character and space. The algorithm of Corollary 3.2 uses time per character space. Furthermore, sketches are retrieved, which takes time (Corollary 3.2) and maintaining weights requires time and space. Finally, the majority vote algorithm takes space and time. In total, the algorithm takes space and time.
We now apply the lemma above to preprocess as follows. We maintain the -mismatch sketch of using Corollary 3.2. ˜3.4 ensures that if there are at least occurrences of in , then there exists a primitive string of length such that . For brevity, let . We apply Lemma 3.12 to and condition on the fact that it outputs , , and before or upon the arrival of . By an application of ˜3.1, we compute and then using . To finish the preprocessing, we compute one more sketch:
Lemma 3.13.
Assume there are -mismatch occurrences of in . There is a streaming algorithm that uses space and time per character, and computes for and correctly w.h.p. upon arrival of , where is the endpoint of the first -mismatch occurrence of in .
Proof.
By the condition of the lemma, is defined and we assume to have computed it by arrival of , where and . We run two instances of the -mismatch algorithm: One for a pattern and , and the other for and . Assume that we detect a -mismatch occurrence of ending at a position . Let . We compute via Corollary 3.2, and via Proposition 2.9. If is not the ending position of a -mismatch occurrence of , we discard the computed information and continue. Otherwise, we have . At the position the -mismatch algorithm extracts in time, and we use it to extract from in time as well. Note that the size of the extracted mismatch information is at most by ˜3.4. Finally, we apply ˜3.1 to compute from and in time and space. Similarly, with and the mismatch information, we compute in time and space. (See Figure 2 for an illustration.)
To show the complexity of the algorithm, we need to understand the structure of the -mismatch occurrences of in . As each -mismatch occurrence of starts with a -mismatch occurrence of , contains at least -mismatch occurrences of the latter. Since , by ˜3.4 there is a primitive string such that and . By Lemma 3.5, , and again by ˜3.4, the difference between the starting positions of any two -mismatch occurrences of in is a multiple of . Therefore, we never process more than two -mismatch occurrences of at a time and the bounds follow.
This information will allow us computing the sketches necessary for Proposition 3.6.
3.4.1 Main phase of the algorithm
The main phase distinguishes two cases: and . For , we show the following result:
Proposition 3.14.
Assume that and that has more than -mismatch occurrences in . The algorithm computes , and for in time and space and is correct w.h.p.
Proposition 3.14 can be proven using the same ideas as in the case , but needs some additional care because the size of the pattern being large ( or ) leads to edge cases that are treated separately. Below, we focus on the case . We start by extending into a prefix (Algorithm 1).
The following inequalities are essential for analysis of correctness of the algorithm:
Proposition 3.15.
For , we have and .
Proof.
We start by showing the first inequality:
To show the second inequality, note that
We now discuss how to implement Algorithm 1. As we know before or upon the arrival of , Algorithm 1 can be implemented in streaming via Corollary 3.2, ˜3.1 to use space and time per character. Furthermore, it always terminates before the arrival of (Proposition 3.15) and outputs , and , and and . Define . Note that is well-defined by Proposition 3.15. Furthermore, let , , and . From ˜3.7 and Proposition 3.15 we obtain:
Corollary 3.16.
The set is a subset of the set of the starting positions of -mismatch occurrences of in , and consequently of the set of the starting positions of -mismatch occurrences of in .
Consider now two subcases depending on the line where Algorithm 1 executes the return.
Return is executed in Line 6
Proposition 3.17.
The prefixes and have the following properties:
-
1.
The number of -mismatch occurrences of in is .
-
2.
The distance between any two -mismatch occurrences of in is a multiple of .
Proof.
To show the first part of the claim, note that and . Assume, for sake of contradiction, that there are more than occurrences of in . By ˜3.4, there is a primitive string , , such that . By Lemma 3.5, , a contradiction.
We now show the second part of the claim. Note that and hence . Next, we have two cases: and . In the first case, every position which is a starting position of a -mismatch occurrence of in is also a starting position of a -mismatch occurrence of in . Hence, there are at least -mismatch occurrences of in , and by ˜3.4, there is a primitive string , , such that . By Lemma 3.5, . If , then by construction. Consequently, by applying ˜3.4 one more time, we obtain that the difference between the starting positions of any two -mismatch occurrences of in is .
We apply the -mismatch algorithm to detect -mismatch occurrences of and in the text . In parallel, we maintain two hash tables of size at most each, and , implemented via ˜3.8. When we receive a character , the tables are updated as follows. Assume first that the -mismatch algorithm detects a new occurrence of ending at the position . We retrieve and . From the mismatch information, and we compute , and we memorise associated with the sketch and the weight for the next positions. Importantly, at every moment the algorithm stores at most one position-sketch pair by Proposition 3.17. By the definition of and , the -mismatch occurrences detected by the algorithm can only start before , and consequently , which implies .
Now, assume that . In this case, we immediately compute via the following claim and memorise it for the next positions:
Proposition 3.18.
Assume to be given , , and . There is an algorithm that uses space and time and computes . The algorithm succeeds w.h.p.
Proof.
By Corollary 3.16 and Proposition 3.17, for some integer . Consequently, the sketch can be computed as follows. First, the algorithm computes and . Secondly, it computes and then deduces in space and time via ˜3.1. Finally, it computes from and .
Also, if the current position equals , where is the position in the stored position-sketch pair, we memorise . Again, by Proposition 3.17 the algorithm stores at most one sketch at a time. If the current position is the endpoint of a -mismatch occurrence of in , the position is necessarily the endpoint of a -mismatch occurrence of in , and we store associated with and . We add this triple to . In addition, if , we have already computed , and we add it to . Finally, if is the current position and for we have , we add associated with to .
If any of the insertions takes more than constant time or if the size of any of and becomes larger than , the algorithm terminates and returns .
When the entire string has arrived, the algorithm considers each position , extracts from and from and if passes the test of Proposition 3.6, reports as a -mismatch period of , and also returns (undefined if one of the values on the right is undefined), and .
Return is executed in Line 7
Proposition 3.19.
If return is executed in Line 7, we have and for all there is .
Proof.
The first part of the claim is immediate by construction. To show the second part, recall that . Hence,
We run the -mismatch algorithm (Corollary 3.3) for and . If a position is the endpoint of the first -mismatch occurrence of in , we retrieve and , and deduce with the same method as in the previous case. Also, we memorise , the sketch, the mismatch information and the weight. We would now like to process the last -mismatch occurrence of in in a similar way. As it is not possible to say in advance whether the current -mismatch occurrence is the last one, we instead do the following. Starting from the second endpoint of a -mismatch occurrence of in , we retrieve by Corollary 3.3, and memorise and the mismatch information until the next -mismatch occurrence is detected, when they are discarded. Additionally, at the position we launch a new instance of the algorithm of Corollary 3.2, maintaining . Again, if we detect another -mismatch occurrence, we discard the currently stored sketch. In addition, when arrives, for we launch a new instance of the algorithm in Corollary 3.2, maintaining . This way, when we reach the end of , we have the following information at hand:
-
1.
For the endpoint of the first -mismatch occurrence of in , , weight , and the mismatch information ;
-
2.
For the endpoint of the last -mismatch occurrence of in , the mismatch information and ;
-
3.
for .
By Proposition 3.19 and ˜3.4, we have . We test each position in the latter set as follows (see Figure 3):
- 1.
-
2.
Compute . First, retrieve from and , and the mismatch information , , and in time and space. Second, compute (undefined if one of the values on the right is undefined).
-
3.
Compute . If , we already know the sketch. Otherwise, by Proposition 3.19 . Additionally, for an integer defined as in Lemma 3.13. Hence, can be computed via ˜3.1: start by computing from , , and the mismatch information for and , and then use to compute .
-
4.
Compute using the computed sketches via ˜3.1. If it is at most , output as a -mismatch period, and return and .
Proposition 3.20.
Assume that and that has more than -mismatch occurrences in . The algorithm computes , and for in time and space and is correct w.h.p.
Proof.
The preprocessing of takes time and space. The main phase of the algorithm starts with an extension procedure (Algorithm 1), which takes total time and space. If the return is executed in Line 6 of Algorithm 1, the algorithm then runs two instances of the -mismatch algorithm (Corollary 3.3) that take time and space. Adding elements to and , as well as look-ups, takes time per element, and we add at most elements in total. The two hash tables occupy space (˜3.8, ˜3.1). Finally, testing all candidate positions requires time and space (Proposition 3.6). If the return is executed in Line 7 of Algorithm 1, the algorithm runs an instance of the -mismatch algorithm, which takes time and space, and maintains a constant number of sketches, taking time and space. The process to test the candidate -periods uses space and time, and it is iterated times.
The algorithm can fail if the preprocessing fails, if the -mismatch algorithm errs, or if adding an element to the hash tables takes more than constant time, or if the test fails. By the union bound, Corollary 3.3, ˜3.1, and Proposition 3.6, the failure probability is inverse-polynomial in .
Theorem 2.10 follows from Proposition 3.10, Proposition 3.20, and Proposition 3.14.
References
- [1] Gabriel Bathie, Tomasz Kociumaka, and Tatiana Starikovskaya. Small-space algorithms for the online language distance problem for palindromes and squares. In ISAAC 2023, volume 283 of LIPIcs, pages 10:1–10:17, 2023. doi:10.4230/LIPICS.ISAAC.2023.10.
- [2] Michael A. Bender, Martín Farach-Colton, John Kuszmaul, and William Kuszmaul. Modern hashing made simple. In SOSA 2024, pages 363–373, 2024. doi:10.1137/1.9781611977936.33.
- [3] Petra Berenbrink, Funda Ergün, Frederik Mallmann-Trenn, and Erfan Sadeqi Azer. Palindrome recognition in the streaming model. In STACS 2014, volume 25, pages 149–161, 2014. doi:10.4230/LIPIcs.STACS.2014.149.
- [4] Sudatta Bhattacharya and Michal Koucký. Locally consistent decomposition of strings with applications to edit distance sketching. In STOC 2023, pages 219–232, 2023. doi:10.1145/3564246.3585239.
- [5] Sudatta Bhattacharya and Michal Koucký. Streaming k-edit approximate pattern matching via string decomposition. In ICALP 2023, volume 261 of LIPIcs, pages 22:1–22:14, 2023. doi:10.4230/LIPICS.ICALP.2023.22.
- [6] Sudatta Bhattacharya and Michal Koucký. Locally consistent decomposition of strings with applications to edit distance sketching, 2023. doi:10.48550/arXiv.2302.04475.
- [7] Robert S. Boyer and J Strother Moore. MJRTY: A fast majority vote algorithm. In Automated Reasoning: Essays in Honor of Woody Bledsoe, Automated Reasoning Series, pages 105–118. Kluwer Academic Publishers, 1991.
- [8] Panagiotis Charalampopoulos, Tomasz Kociumaka, and Philip Wellnitz. Faster approximate pattern matching: A unified approach. In FOCS 2020, pages 978–989. IEEE, 2020. doi:10.1109/FOCS46700.2020.00095.
- [9] Raphaël Clifford, Tomasz Kociumaka, and Ely Porat. The streaming k-mismatch problem. In SODA 2019, pages 1106–1125. SIAM, 2019. doi:10.1137/1.9781611975482.68.
- [10] Richard Cole and Ramesh Hariharan. Approximate string matching: A simpler faster algorithm. In Howard J. Karloff, editor, SODA 1998, pages 463–472. ACM/SIAM, 1998. URL: http://dl.acm.org/citation.cfm?id=314613.314827.
- [11] Mohamed G. Elfeky, Walid G. Aref, and Ahmed K. Elmagarmid. Stagger: Periodicity mining of data streams using expanding sliding windows. In ICDM 2006, pages 188–199, 2006. doi:10.1109/ICDM.2006.153.
- [12] Funda Ergün, Elena Grigorescu, Erfan Sadeqi Azer, and Samson Zhou. Streaming periodicity with mismatches. In APPROX/RANDOM 2017, volume 81 of LIPIcs, pages 42:1–42:21, 2017. doi:10.4230/LIPICS.APPROX-RANDOM.2017.42.
- [13] Funda Ergün, Elena Grigorescu, Erfan Sadeqi Azer, and Samson Zhou. Periodicity in data streams with wildcards. Theory Comput. Syst., 64(1):177–197, 2020. doi:10.1007/S00224-019-09950-Y.
- [14] Funda Ergun, Hossein Jowhari, and Mert Sağlam. Periodicity in streams. In APPROX/RANDOM 2010, pages 545–559, 2010.
- [15] Funda Ergün, Elena Grigorescu, Erfan Sadeqi Azer, and Samson Zhou. Streaming periodicity with mismatches, 2017. arXiv:1708.04381.
- [16] Pawel Gawrychowski, Oleg Merkurev, Arseny M. Shur, and Przemyslaw Uznanski. Tight tradeoffs for real-time approximation of longest palindromes in streams. Algorithmica, 81(9):3630–3654, 2019. doi:10.1007/s00453-019-00591-8.
- [17] Tomohiro I. Longest Common Extensions with Recompression. In CPM 2017, volume 78 of LIPIcs, pages 18:1–18:15, 2017. doi:10.4230/LIPIcs.CPM.2017.18.
- [18] John C. Kieffer and En-Hui Yang. Grammar-based codes: A new class of universal lossless source codes. IEEE Trans. Inf. Theory, 46(3):737–754, 2000. doi:10.1109/18.841160.
- [19] Gad M. Landau and Uzi Vishkin. Fast string matching with k differences. Journal of Computer and System Sciences, 37(1):63–78, 1988. doi:10.1016/0022-0000(88)90045-1.
- [20] Markus Lohrey. Algorithmics on slp-compressed strings: A survey. Groups Complex. Cryptol., 4(2):241–299, 2012. doi:10.1515/GCC-2012-0016.
- [21] Oleg Merkurev and Arseny M. Shur. Computing the maximum exponent in a stream. Algorithmica, 84(3):742–756, 2022. doi:10.1007/s00453-021-00883-y.
- [22] Rasmus Pagh and Flemming Friche Rodler. Cuckoo hashing. J. Algorithms, 51(2):122–144, 2004. doi:10.1016/J.JALGOR.2003.12.002.
Appendix A A gap in the previous streaming algorithm for computing -mismatch periods
In this section, we point to the specific claim in the correctness proof of the previous streaming algorithm for computing -mismatch periods [15] which is, in our opinion, not true.
Let be a string length , and two -mismatch periods of such that , where is a position of , and . The construction of [15] introduces a grid defined over a set . A node of the grid represents a position of . For a node representing a position , we add edges connecting it to nodes representing , , , and (if they exist in the grid). Finally, we say that an edge of the gird is bad if .
The proof of [15, Theorem 28], one of the key elements of the streaming algorithm of Ergün et al., relies on the fact that there are a few bad edges in the grid. One of the steps in their proof of this fact is the following claim:
Proposition A.1 ([15, Claim 20]).
The nodes of the grid correspond to distinct positions of .
As an immediate corollary, and since and are both -mismatch periods of , they immediately derive that there are at most bad edges in the grid.
The authors then extend their approach to the case when has -mismatch periods , where . One can construct an -dimensional grid in a similar way to the case , and it is claimed that in this grid, “the total number of bad edges is at most ” (Page 21). However, consider the string . All integers smaller than are -mismatch periods of , and in this example we have , and , verifying the assumption . Let be the grid centred around the index (i.e the only character b). Similarly to the case , a point of the grid represents the position , and an edge between nodes representing positions is bad if . Note for any , the node with , and for represents the position . As a result, is represented by at least distinct different nodes in the grid, which contradicts Proposition A.1 for . Furthermore, these nodes are connected with each of their neighbours with a bad edge. Since each node has at least neighbours, there are at least distinct bad edges, contradicting the upper bound on the number of bad edges which was .
