## Online Computation of String Net Frequency

Peaker Guo 1[0000 - 0002 - 9098 - 1783] , Seeun William Umboh 1 3[0000 , - 0001 - 6984 - 4007] , Anthony Wirth 1 2[0000 , - 0003 - 3746 - 6704] , and 1[0000 - 0001 - 6622 - 032 X ]

Justin Zobel

1

School of Computing and Information Systems, The University of Melbourne

zifengg@student.unimelb.edu.au,

william.umboh@unimelb.edu.au,

awirth@unimelb.edu.au,

jzobel@unimelb.edu.au

2

School of Computer Science, The University of Sydney

anthony.wirth@sydney.edu.au

3 ARC Training Centre in Optimisation Technologies, Integrated Methodologies, and Applications (OPTIMA)

Abstract. The net frequency (NF) of a string, of length m , in a text, of length n , is the number of occurrences of the string in the text with unique left and right extensions . Recently, Guo et al. [CPM 2024] showed that NF is combinatorially interesting and how two key questions can be computed efficiently in the offline setting. First, single-nf : reporting the NF of a query string in an input text. Second, all-nf : reporting an occurrence and the NF of each string of positive NF in an input text. For many applications, however, facilitating these computations in an online manner is highly desirable. We are the first to solve the above two problems in the online setting, and we do so in optimal time, assuming, as is common, a constant-size alphabet: single-nf in O ( m ) time and all-nf in O ( n ) time. Our results are achieved by first designing new and simpler offline algorithms using suffix trees, proving additional properties of NF, and exploiting Ukkonen's online suffix tree construction algorithm and results on implicit node maintenance in an implicit suffix tree by Breslauer and Italiano.

Keywords:

Suffix trees · implicit nodes · suffix links · Weiner links

## 1 Introduction

The net frequency (NF) of a string S , of length m , in a text T , of length n , is the number of occurrences of S in T with unique left and right extensions . For example, let T be rstkstcastarstast$ . Among the five occurrences of st , only the underlined occurrence has a unique left extension kst and a unique right extension stc . In contrast, the other occurrences of st either have a repeated left extension ( rst and ast ), or a repeated right extension ( sta ). Thus the NF of st is 1 in T . Introduced by Lin and Yu [14], NF has been demonstrated to be useful for Chinese phoneme-to-character (and character-to-phoneme) conversion and other NLP tasks [14,15].

Recently, Guo et al. [10] reconceptualised NF and simplified the original definition. They thus identified strings with positive NF, including in Fibonacci

words. They also showed that there could be at most n distinct strings in T with positive NF. They then bounded the sum of lengths of strings with positive NF in T of length n between Ω n ( ) and O ( n log δ ) , where δ := max { S k /k ( ) : k ∈ [ n ] } and S k ( ) is the number of distinct strings of length k in T .

Although NF can be efficiently computed in the offline setting [10], it is also useful to determine NF in an online setting in which a text is being dynamically extended. In this setting, at all times we have read the first n characters from a stream and further characters are to be read in turn, that is, n is being incremented. As each character arrives, the data structure is updated and a query on NF computation can be answered. Throughout our inspection of the online setting, T is an input text of which we have read the first n characters, while S is a lengthm query string. We consider the following two problems in the online setting. single-nf : report the NF of S in T [1 . . . n ] . all-nf : for each string of positive NF in T [1 . . . n ] , report one occurrence and its NF.

We have found that adapting the existing offline approach based on a suffix array to the online setting is not trivial. In the offline setting, suppose we have read n characters of an input text T so far, after building the structure for T [1 . . . n ] , should we append a single character to T , we would have to build the structure for T [1 . . . n + 1] from scratch, without reusing the structure for T [1 . . . n ] . In contrast, in this paper, the structure for T [1 . . . n +1] derives from the structure for T [1 . . . n ] . This setting aligns with the online suffix tree construction algorithm by Ukkonen [21], which is widely used due to its simplicity and online nature, cited in numerous follow-up works [6,7,12,13,20].

Our contribution. In this work, we first introduce a new characteristic of NF (Theorem 2), specifically designed for NF computation with a suffix tree. With this characteristic and Weiner links, assuming a constant-size alphabet, we present our optimal-time offline single-nf algorithm (Algorithm 1). Applying this characteristic in an asynchronous fashion, our optimal-time offline all-nf algorithm (Algorithm 2) using suffix links is arguably simpler than the state-ofthe-art suffix array-based solution. We then adapt our offline algorithms to the online setting - to our knowledge online algorithms have not previously been reported. With additional properties of NF and prior results on implicit nodes in an implicit suffix tree, we obtain optimal O ( m ) -time online single-nf and O ( n ) -time online all-nf algorithms (Theorem 3 and Theorem 4).

## 2 Preliminaries

Strings. Let Σ be a constant-size alphabet throughout this paper. The constantsize assumption follows previous work on suffix trees [6,13]. Let SP ≡ S · P be the concatenation of two strings, S and P . Let [ n ] denote the set { 1 2 , , . . . , n } . A substring of string T with starting position i ∈ [ n ] and end position j ∈ [ n ] is written as T i . . . j [ ] . A substring T [1 . . . j ] is called a prefix of T , while T i . . . n [ ] is called a suffix of T . Let T i denote the i th suffix of T , T i . . . n [ ] . An occurrence in the text T is a pair of starting and ending positions ( i, j ) ∈ [ n ] × [ n ] . We say

( i, j ) is an occurrence of string S if S = T i . . . j [ ] , and i is an occurrence of S if S = T i . . . i [ + | S | -1] . An occurrence ( i , j ′ ′ ) is a sub-occurrence of ( i, j ) if i ≤ i ′ , while j ′ ≤ j . The frequency of S (in T ), denoted by f ( S ) , is the number of occurrences of S in T .

Net frequency. The NF of a string was originally defined by Lin and Yu [14], and reconceptualised and simplified by Guo et al. [10]. The NF of a unique string is defined to be zero; the NF of a repeated string S , written as ϕ S ( ) , is the number of occurrences of S with unique left and right extensions.

Definition 1 (Net occurrence [10]). An occurrence ( i, j ) is a net occurrence if f ( T i . . . j [ ]) ≥ 2 , f ( T i [ -1 . . . j ]) = 1 , and f ( T i . . . j [ +1]) = 1 . When i = 1 , f ( T i [ -1 . . . j ]) = 1 is assumed to be true; when j = n , f ( T i . . . j [ +1]) = 1 is assumed to be true.

NF can be also formulated in terms of symbols from Σ , rather than occurrences.

Lemma 1 (NF characteristic [10]). Given a repeated string S ,

$$\phi ( S ) = \left | \left \{ \, ( x, y ) \in \Sigma \times \Sigma \, \colon f ( x S ) = 1 \ a n d \ f ( S y ) = 1 \ a n d \ f ( x S y ) = 1 \, \right \} \right | \,.$$

Here, strings xS , Sy , and xSy are the left , right , and bidirectional extensions of S , respectively. Note that in Definition 1, the condition on the bidirectional extension f ( T i [ -1 . . . j +1]) = 1 is not needed because it is implied by f ( T i [ -1 . . . j ]) = 1 and f ( T i . . . j [ + 1]) = 1 . A string S is branching in T if S is the longest common prefix of two distinct suffixes of T . The following result says that branching strings are the only strings that could have positive NF.

Lemma 2 ([10]). If S is not a branching string, then ϕ S ( ) = 0 .

Suffix trees. Introduced by Weiner [22], the suffix tree is arguably one of the most significant and versatile data structures in string processing with a wide range of applications [11]. The suffix tree of T is a rooted directed tree whose edges are labelled with substrings of T . It contains n leaf nodes, each labelled from 1 to n . For each i ∈ [ n ] , the concatenation of the edge labels on the path from the root to leaf i forms the suffix T i . Each non-root and non-leaf node, known as a branching node , has at least two children, and the first character of the label on the edge to each child is distinct.

It is commonly assumed that a unique sentinel character $ / Σ ∈ is appended to the text. This ensures that no suffix is a prefix of another, thereby ensuring that each suffix is represented as a distinct leaf in the suffix tree. Given a node u , the path label of u , denoted by str( u ) , is the concatenation of the edge labels on the path from the root to u . We call | str( u ) | the string depth of u , denoted by depth( u ) .

In suffix-tree construction algorithms [16, 21, 22], a type of pointer called a suffix link 4 helps traverse the suffix tree efficiently; it is a key ingredient in

4 Asuffix link is also referred to as a vine pointer in the Prediction by Partial Matching algorithm [17] or as a failure link in the Aho-Corasick algorithm [2].

achieving linear time. In our algorithms, besides suffix links, we also use Weiner links , also known as reverse suffix links . Given a branching node, u , the suffix link of u points from u to another branching node, v , where str( v ) is the string obtained by removing the first character of str( u ) , that is, the longest proper suffix of str( u ) . Whenever there is a suffix link from u to v , there is a Weiner link from v to u . Suffix links and Weiner links are usually only needed among branching nodes, but some applications also require them among leaf nodes [19].

̸

̸

We now define the following notations in a suffix tree used in subsequent sections. Consider a node u . Let start( u ) be the starting position of some occurrence of str( u ) in the text. Let parent( u ) be the parent node of u . Let child( u, y ) be the child node v of u such that the label of the edge uv starts with symbol y , and ⊥ if such v does not exist. Let children( u ) := { ( v, y ) : v = child( u, y ) = ⊥} . Let slink( u ) be the node that receives the suffix link from u . Let wlink( u, x ) be the node v that receives a Weiner link from u and whose path label is str( v ) = x · str( u ) , and ⊥ if such v does not exist. Let wlinks( u ) := { ( v, x ) : v = wlink( u, x ) = ⊥} .

A suffix tree of T can be also defined as a trie for all the suffixes of T where each non-branching path is compressed into a single edge. A locus in a suffix tree corresponds to a node in the uncompressed trie. More precisely, it is a location in the suffix tree specified as a pair ( u, d ) where u is a node and d is an integer that satisfies depth(parent( u )) &lt; d ≤ depth( u ) .

Given a substring S of T , after traversing the suffix tree from the root following the characters in S , the traversal always ends at a unique locus, ( u, d ) . We say the traversal ends within an edge if d &lt; depth( u ) and ends at a node if d = depth( u ) . Observe that the frequency of S equals the number of leaf nodes in the subtree rooted at u . So S is unique if u is a leaf node and is repeated if u is a branching node. Also note that S = str( u )[1 . . . d ] .

Implicit suffix trees. The implicit suffix tree of a text can be defined by modifying its suffix tree as follows. First, every edge with only the sentinel character, $ , as its label is removed. Then, for each node u with only one child, v , we perform these operations: let w := parent( u ) ; remove node u , together with edges wu and uv ; and create a new edge from w to v with edge label T [start( v )+depth( w ... ) start( v )+depth( v )] , the concatenation of the edge labels of wu and uv . The tree obtained is called an implicit suffix tree . In an implicit suffix tree, branching nodes and leaf nodes are referred to as explicit nodes . Note that in a suffix tree, each suffix is unique and corresponds to a distinct leaf node. However, in an implicit suffix tree, repeated suffixes do not correspond to leaf nodes. For example, the repeated suffixes of the text aabaabababaa are the strings a , aa , baa , and abaa .

Definition 2 (Implicit node). An implicit node ( u, d ) is a locus such that str( u )[1 . . . d ] is a repeated suffix of the text.

Each implicit node in an implicit suffix tree corresponds to a branching node in the suffix tree with only two children and one of them is $. Note that if an

implicit node satisfies d = depth( u ) , then it coincides with a branching node in the implicit suffix tree. Figure 1 demonstrates the major aspects of the suffix tree and implicit suffix tree. On its right, among the implicit nodes numbered 10-12, node 12 coincides with a branching node.

The key idea of Ukkonen's algorithm is successive building of implicit suffix trees for each prefix of the text, then adding the $ at the end. The algorithm maintains a pointer called the active point to the locus of the longest repeated suffix of the text. One limitation of Ukkonen's algorithm is that the locations of the implicit nodes are not maintained during suffix tree construction. Breslauer and Italiano [6] provide techniques for such task and extend Ukkonen's algorithm. They also further classify edges and nodes in an implicit suffix tree.

Definition 3. An edge uv is called an external edge if v is a leaf node and an internal edge otherwise. An implicit node u is called an internal implicit node if u is within an internal edge and an external implicit node otherwise.

If the locus each suffix corresponds to has an outgoing suffix link (including leaf and implicit nodes), then these suffix links form a path, which is called the suffix chain by Breslauer and Italiano. The path starts from the leaf labelled by T and ends at the root, going through each suffix and satisfying the following.

Lemma 3 ([6]). The suffix chain can be partitioned into the following consecutive segments: leaves, external implicit nodes, internal implicit nodes, and implicit nodes that coincide with branching nodes.

On the right of Figure 1, these segments are: nodes 1-8, 9-10, 11, and 12. The main result by Breslauer and Italiano that we use together with Ukkonen's online suffix tree construction algorithm is summarised as follows.

Theorem 1 ([6, 21]). An implicit suffix tree on the first n characters of T , together with the suffix links and Weiner links can be built in O ( n ) amortized time. A query returning the implicit nodes within a specific suffix tree edge takes worst-case O (1) time.

Breslauer and Italiano showed that there is at most one implicit node within an internal edge. Although each external edge may contain multiple implicit nodes, their representation as an arithmetic progression can be returned in O (1) time [6]. This result also supports other queries in the online setting [13].

## 3 Offline NF Computation with Suffix Trees

We present our suffix-tree based approaches for offline NF computation, which are arguably simpler than the suffix-array based approaches [10]. We adapt them from the offline to the online setting in the following section.

Fig. 1: The suffix tree (left) and implicit suffix tree (right) for text aabaabababaa . Leaves (squares) and implicit nodes (red dots) are numbered; green arrows are suffix links coming from branching nodes.

![Image](https://ac.marcodsn.me/arxiv-markdown-images/2408.00308v1-figure-13da4760-a39d-49e5-9140-5b2fd0b4ce3f.jpg)

## 3.1 Offline single-nf Algorithms

The NF characteristic for suffix array might lead to explicit character matching in a suffix tree. Moreover, when leaf nodes do not have incoming Weiner links, we are unable to enumerate unique left extensions of a string; so Lemma 1 is unhelpful with a suffix tree. We therefore introduce a new characteristic, which is more suitable for computing NF in a suffix tree. Essentially, it bypasses enumerating unique left extensions of the string.

Theorem 2 (Suffix tree NF characteristic). Given a repeated string S , let L S ( ) := { x ∈ Σ : f ( xS ) ≥ 2 } and r S ( ) := { y ∈ Σ : f ( Sy ) = 1 } , then

$$\phi ( S ) = | r ( S ) | - \sum _ { x \in L ( S ) } | r ( x S ) \cap r ( S ) | \,.$$

Proof. We first define the following three sets:

$$L _ { = 1 } & \coloneqq \left \{ ( x, y ) \in \Sigma \times \Sigma \, \colon f ( x S ) = 1 \text{ and } f ( S y ) = 1 \text{ and } f ( x S y ) = 1 \right \}, \\ L _ { \geq 1 } & \coloneqq \left \{ ( x, y ) \in \Sigma \times \Sigma \, \colon f ( x S ) \geq 1 \text{ and } f ( S y ) = 1 \text{ and } f ( x S y ) = 1 \right \}, \text{ and } \\ L _ { \geq 2 } & \coloneqq \left \{ ( x, y ) \in \Sigma \times \Sigma \, \colon f ( x S ) \geq 2 \text{ and } f ( S y ) = 1 \text{ and } f ( x S y ) = 1 \right \}.$$

Observe that | L =1 | = | L ≥ 1 | - | L ≥ 2 | and ϕ S ( ) = | L =1 | . Next, note that for each y ∈ Σ , if f ( Sy ) = 1 , then f ( xSy ) ≤ 1 holds for each x ∈ Σ . Further, if f ( xSy ) = 1 then f ( xS ) ≥ 1 ; otherwise, f ( xSy ) = 0 and f ( xS ) = 0 . Thus, we have | r S ( ) | = | L ≥ 1 | . Finally, we derive that ∑ x ∈ L S ( ) | r xS ( ) ∩ r S ( ) | = ∣ ∣ ⋃ ∣ x ∈ L S ( ) r xS ( ) ∩ r S ( ) ∣ ∣ ∣ = | L ≥ 2 | . Therefore, we have proved the desired result. ⊓ ⊔

## Algorithm 1: for offline single-nf

```
  Algorithm 1: for offline SINGLE-NF
  
  1  (u, d) <- the locus of a query string S;
      // unique or non-branching strings have zero NF (Lemma 2)
  2  if u is a leaf or d < depth(u) then return 0;
      // initialise the NF of S by counting |r(S)| in Theorem 2
  3  @ <- the number of leaf child nodes of u;
      // if |r(S)| = 0, then  @(S) = 0 (Corollary 1)
      if  @ = 0 then return 0;
      // compute \_z\nL(S) |r(zS) \_r(S)| in Theorem 2
      foreach (v, x) \nelinks(u) do
      |    foreach (w, y) \nelchildren(v) do
          |     // xSy and Sy are both unique (Proposition 1)
          |     if  w is a leaf and child(u, y) is a leaf then                                                                                                                                                                                                        
                                                                                                                                                                                                       

      return
```

Take T = rstkstcastarstast$ and S = st as an example. We have r S ( ) = { $ c k , , } and L S ( ) = { r a , } . When x = r , r ( xS ) = { a k , } and r xS ( ) ∩ r S ( ) = { k } . When x = a , r ( xS ) = { $ a , } and r xS ( ) ∩ r S ( ) = { $ } . Thus, ϕ S ( ) = 3 -(1+1) = 1 . The following informs checking of whether a right extension is unique.

Proposition 1. Consider a branching node u and y ∈ Σ . Let S := str( u ) , then, Sy is unique if child( u, y ) is a leaf.

Theorem 2 immediately suggests a criterion for early termination of the algorithm when it is determined that the NF of the query string is zero.

$$\text{Corollary $1$. $IF$} \left | r ( S ) \right | = 0, \text{ then } \phi ( S ) = 0.$$

Lemma 2 was introduced to narrow down candidates with a potentially positive NF when solving all-nf . However, due to certain limitations of a suffix array, the result could not be efficiently applied to single-nf . Now, with a suffix tree, we can utilise this result to detect a zero NF input string for single-nf .

Our single-nf algorithm using a suffix tree is presented in Algorithm 1. It uses Lemma 2 and Corollary 1 for zero NF detection. The algorithm computes the two terms in Theorem 2 separately and also utilises Weiner links for left extension enumeration. The correctness of the algorithm follows from Theorem 2.

Given a string S , Algorithm 1 runs in O | ( S | ) time in the worst case. Locating the locus of S in the tree takes O | ( S | ) time. Computing | r S ( ) | takes at most O | ( Σ | ) time, a constant in our analysis. Then the time to compute ∑ x ∈ L S ( ) | r xS ( ) ∩ r S ( ) | is bounded by | Σ | 2 , also a constant.

## 3.2 Offline all-nf Algorithm

From Lemma 2, only branching strings could have positive NF. In this section, we present an offline all-nf algorithm that extracts and stores the NF of each

![Image](https://ac.marcodsn.me/arxiv-markdown-images/2408.00308v1-figure-e2769f23-e3c9-459a-ab8b-132fa7060b79.jpg)

branching string in its corresponding branching node in the suffix tree. The stored positive NF values can be reported afterwards.

In Algorithm 1, the two terms in in Theorem 2 are computed in separate steps of the algorithm. For our all-nf algorithm, we compute these two terms in an asynchronous fashion: before we finish computing the NF of one branching string, we might start computing the NF of another branching string. In other words, the NF of each branching string is partially computed and updated as the algorithm progresses. Specifically, suppose we are visiting a branching node v , let u := slink( v ) , xS := str( v ) , and S := str( u ) . We update the NF for both xS and S as follows. We compute | r xS ( ) | to update ϕ xS ( ) and compute | r xS ( ) ∩ r S ( ) | to update ϕ S ( ) . Note that, after visiting node v , it is possible that neither ϕ xS ( ) nor ϕ S ( ) has the correct value, as they may have only been partially computed. But at the end of the algorithm, each NF value will be correct.

Our offline all-nf algorithm is listed in Algorithm 2 and illustrated in Figure 2. It does not require traversing the branching nodes in a particular order, and runs in O ( n ) time in the worst case. Since checking whether a node is a leaf takes O (1) time, the overall time usage is bounded by the number of nodes visited throughout execution. Given a branching node, u , each of its child nodes, w , is visited exactly once; each node in the suffix tree is the child node of exactly one branching node. Moreover, there are at most n branching nodes in the tree. Thus, the total number of nodes visited is bounded by O ( n ) .

## 4 Online NF Computation with Implicit Suffix Trees

With our offline algorithms, we first introduce additional properties of NF then present our online algorithms based on these results.

## 4.1 Online single-nf Algorithm

Our offline single-nf algorithm computes the two terms in Theorem 2 for a query string whose locus is a branching node. In the online setting, our online

Fig. 3: Illustration of Lemma 4: Case 1 (left), Case 2 (middle), and Case 3 (right). Black dots, coloured dots, and squares represent branching nodes, implicit nodes, and leaves, respectively. Each dashed (non-existent) edge has label $ and leads to a dashed (non-existent) leaf node. In each case, each implicit node has its own colour. The implicit node ( u, d ) is also labelled, and the leaf nodes corresponding to its unique right extensions share the same colour as ( u, d ) .

![Image](https://ac.marcodsn.me/arxiv-markdown-images/2408.00308v1-figure-fa2a733c-5b1d-430e-9713-d4b04e593acc.jpg)

approach is still based on Theorem 2, but also taking implicit nodes into account in the implicit suffix tree. We first reconsider Proposition 1, as Proposition 2.

Proposition 2. Consider a branching node, u , and y ∈ Σ . Let S := str( u ) , then, Sy is unique if v := child( u, y ) is a leaf and edge uv has no implicit node.

Let ( u, d ) be the locus of the query string S . In the offline case, | r S ( ) | in Theorem 2 is computed by simply counting the number of leaf child nodes of u . But it is more involved in the online setting.

Definition 4. Consider an implicit node ( u, d ) and let ρ u, d ( ) denote the number of unique right extensions of str( u )[1 . . . d ] .

Lemma 4. Consider an implicit node ( u, d ) and let S := str( u )[1 . . . d ] . The following cases are illustrated in Figure 3.

Case 1 If ( u, d ) is an internal implicit node, then ρ u, d ( ) = 1 .

Case 2 If ( u, d ) is an internal implicit node that coincides with a branching node, then ρ u, d ( ) equals one plus the number of leaf child nodes of u whose leading edge does not contain an implicit node.

Case 3 If ( u, d ) is an external implicit node, then ρ u, d ( ) = 2 if ( u, d ) is the deepest such on the edge, and ρ u, d ( ) = 1 otherwise.

Proof. In Case 1, the only unique right extension character is the $. Case 2 follows from Proposition 2, and we add one for the $. In Case 3, the deepest such has the $ and a leaf child, while the others only has the $. ⊓ ⊔

The NF of the longest repeated suffix is given as follows.

Lemma 5. Consider an implicit node ( u, d ) and let S := str( u )[1 . . . d ] . If S is the longest repeated suffix of T , then ϕ S ( ) = ρ u, d ( ) .

Proof. Observe that each occurrence of S has a unique left extension character as otherwise S would not be the longest repeated suffix. So, ϕ S ( ) = ρ u, d ( ) . ⊓ ⊔

The following result provides another zero NF detection mechanism.

Lemma 6. Consider an implicit node ( u, d ) and let S := str( u )[1 . . . d ] . If S is not the longest repeated suffix and ( u, d ) does not coincide with a branching node, then ϕ S ( ) = 0 .

Proof. First consider each occurrence of S that is not a sub-occurrence of an occurrence of the longest repeated suffix: the left extension character of such occurrence is always T n [ -d ] . Next, consider each occurrence of S except the rightmost one: since ( u, d ) does not coincide with a branching node, the right extension character of such occurrence is always T i [ + ] d for any occurrence i of S with i &lt; n -d . Thus, no occurrence of S is a net occurrence and ϕ S ( ) = 0 . ⊓ ⊔

For the remaining case, not covered by Lemma 5 or Lemma 6, the NF of the query string cannot be easily deduced. Further computation, assisted by Weiner links, is required. In Algorithm 1, the recipient of each Weiner link is a branching node, however, for online single-nf , implicit Weiner links, whose recipients are implicit nodes, are also needed. We present the following result on how to compute an implicit Weiner link. The result is illustrated in Figure 4a.

Lemma 7. Consider an implicit node ( u, d ) that coincides with a branching node. Let ( q, ℓ ) be another implicit node such that str( q )[1 . . . ℓ ] = x · str( u )[1 . . . d ] for some x ∈ Σ . Define w := parent( q ) . If there exists an ancestor v of u such that wlink( v, x ) exists, then w = wlink( v ∗ , x ) where v ∗ is the lowest such ancestor of u ; otherwise, w is the root.

Proof. The proof is illustrated in Figure 4b.

̸

If v ∗ exists, let w ′ := wlink( v ∗ , x ) and assume, by contradiction, that w ′ = w . Let P := str( v ∗ ) , then str( w ′ ) = xP . Since xP is a prefix of xS , w ′ is an ancestor of w . Let P ′ := str( w )[2 . . . depth( w )] , then xP ′ = str( w ) . Since w is a branching node, there exists a branching node v ′ with str( v ′ ) = P ′ . This implies that wlink( v , x ′ ) = w . Since v ′ is an ancestor of u , this contradicts that v ∗ is the lowest such ancestor. Thus, our assumption is false and w = w ′ .

If v ∗ does not exist, assume, by contradiction, that w is not the root. Similarly, since w is a branching node, there exists a branching node v ′ such that wlink( v , x ′ ) = w . Since v ′ is an ancestor of u , this contradicts that v ∗ does not exist. Thus, our assumption is false and w is the root. ⊓ ⊔

Note that the concept of implicit Weiner links has also been described before [4, 9,18], but with either a different definition or way of computing them. We next introduce a corollary of Theorem 2 that splits the set L S ( ) into two disjoint sets.

Corollary 2. Consider a locus ( u, d ) with d = depth( u ) . Let S := str( u ) ,

L exp ( S ) := { x ∈ Σ : f ( xS ) ≥ 2 and the locus of xS is an explicit node } ,

L imp ( S ) := { x ∈ Σ : f ( xS ) ≥ 2 and the locus of xS is an implicit node } , and let λ x ( ) := | r xS ( ) ∩ r S ( ) | , then

$$\phi ( S ) = | \rho ( u, d ) | - \sum _ { x \in L _ { e x p } ( S ) } \lambda ( x ) - \sum _ { x \in L _ { i m p } ( S ) } \lambda ( x ) \,.$$

v

=

w

=

r

- (a) Illustration of Lemma 7.

(b) Illustration of proof of Lemma 7.

![Image](https://ac.marcodsn.me/arxiv-markdown-images/2408.00308v1-figure-a428ebaf-aa9c-45e4-842e-80146ff4137f.jpg)

̸

Fig. 4: Let r be the root node of the implicit suffix tree. An edge is shown straight; a path is shown squiggly. In Figure 4a, some possible locations of nodes u w , , and v := parent( u ) are shown: v = r = w (left), v = r = w (top right), v = r = u = w (bottom right). Each green arrow indicates an implicit Weiner link from ( u, d ) to ( q, ℓ ) . In Figure 4b, compare scenarios when v ∗ exists (left) and when v ∗ does not exist (right). A node is coloured grey to indicate that it exists only under false assumption. Next to several nodes are corresponding path labels.

̸

̸

Using Lemma 7 and Corollary 2, together with the results introduced in this section earlier, we present our online single-nf algorithm in Algorithm 3. Computing implicit Weiner links takes O | ( S | · | Σ | 2 ) ⊆ O | ( S | ) time, assuming a constant-size alphabet. The rest of the analysis follows from the analysis of Algorithm 1 and we have the following result.

Theorem 3. Online single-nf can be solved in worst-case O | ( S | ) time.

## 4.2 Online all-nf Algorithm

Our arguably very simple offline all-nf algorithm forms the basis of our online approach. Similar to the online single-nf algorithm, we need to deal with left extensions whose loci are implicit nodes. We make an additional observation.

Lemma 8. Consider a repeated suffix S and its left extension, xS , which is also a repeated suffix. If the locus of xS coincides with a branching node, then the locus of S also does. If the locus of S does not coincide with a branching node, then the locus of xS also does not.

Proof. Consider the suffix chain in Lemma 3 in reverse and we have the desired result. ⊓ ⊔

## Algorithm 3: for online single-nf

̸

```
          P. Guo et al.
           
        Algorithm 3: for online SINGLE-NF
           
        (u, d) <- the locus of a query string S;
        if (u, d) is the active point then return p(u, d); // Lemma 5
        if u is a leaf or d < depth(u) then return 0; // Lemma 2 and Lemma 6
        g += p(u, d); // initialise the NF of S by computing p(u, d) using Lemma 4
        if g = 0 then return 0; // Corollary 1
        // compute \n_\n\n(s) \(x) in Corollary 2
        foreach (w, x) \nkins(u) do
          |                                                                                                                                                                                                        
          |                                                                                                                                                                                            
          |
        if (u, d) is not an implicit node then return g;
        // compute A, the set of implicit Weiner links from (u, d) using Lemma 7
        A += g;  r += the root;  p += u;
        while p \n  r do
         |                                                                                                                                                                                              
         |                                                                                                                                                                                             
        while p \n  r do
         |                                                                                                                                                                              
         |                forach (q, y) \nkins(p) do  // "_" is used when the character is unused
          |                                                                                                                                                                                            

         |                                                                                                                                                                                              

                                                                                                                                                                                                       

        
                                                                                                                                                                                                        }
                                                                                                                                                                                                      

                                                                                                                                                                                                       }

                                                                                                                                                                                                      
With Lemma 8, observe that at most one string might require implicit Weiner
    links: namely, the longest repeated suffix whose locus coincides with a branch-
```

With Lemma 8, observe that at most one string might require implicit Weiner links: namely, the longest repeated suffix whose locus coincides with a branching node. The other repeated suffixes whose locus coincides with a branching node do not have implicit Weiner links. Our online all-nf algorithm is adapted from our offline all-nf algorithm as follows. We first compute the NF of the longest repeated suffix. We then invoke offline all-nf , but use Proposition 2 instead of Proposition 1. While traversing each branching node, we keep track of string depth and find τ , the longest repeated suffix whose locus coincides with a branching node. Once we do, we invoke online single-nf on τ . Overall, the cost is bounded by O ( n + | τ | ) ⊆ O ( n ) where O ( n ) is the cost for offline all-nf and O | ( τ | ) is the cost for online single-nf on τ .

Theorem 4. Online all-nf can be solved in worst-case O ( n ) time.

## 5 Conclusion and Future Work

In this work, we present, to our knowledge, the first and, indeed, optimal-runtime online algorithms for both single-nf and all-nf . Having unsuccessfully investigated online approaches based on suffix arrays - the basis of previous offline methods - we turned our attention to suffix trees, using which we found offline and online algorithms that are runtime-optimal. The results are based on new characteristics and properties of net frequency and prior results on auxiliary pointers in suffix trees and on implicit node maintenance.

An avenue of future work is design and engineering an efficient implementation of our solution, in particular the structures required for implicit nodes such as structures for dynamic nearest marked ancestors in trees [3,8] and structures for ancestor relationships [5].

Acknowledgments. The authors thank Patrick Eades for insightful discussions during the early stage of this work. The authors also thank the anonymous reviewers for their suggestions. This work was supported by the Australian Research Council, grant number DP190102078, and an Australian Government Research Training Program Scholarship.

## References

- 1. 25th Annual Symposium on Combinatorial Pattern Matching, CPM 2014, June 1618, 2014. Moscow, Russia, Lecture Notes in Computer Science, vol. 8486. Springer (2014). https://doi.org/10.1007/978-3-319-07566-2
- 2. Aho, A.V., Corasick, M.J.: Efficient string matching: An aid to bibliographic search. Communications of the ACM 18 (6), 333-340 (1975). https://doi.org/10. 1145/360825.360855
- 3. Amir, A., Farach, M., Idury, R.M., Poutré, J.A.L., Schäffer, A.A.: Improved dynamic dictionary matching. Information and Computation 119 (2), 258-282 (1995). https://doi.org/10.1006/INCO.1995.1090
- 4. Belazzougui, D., Cunial, F.: Fully-functional bidirectional Burrows-Wheeler indexes and infinite-order de Bruijn graphs. In: 30th Annual Symposium on Combinatorial Pattern Matching, CPM 2019, June 18-20, 2019, Pisa, Italy. LIPIcs, vol. 128, pp. 10:1-10:15. Schloss Dagstuhl - Leibniz-Zentrum für Informatik (2019). https://doi.org/10.4230/LIPICS.CPM.2019.10
- 5. Bender, M.A., Cole, R., Demaine, E.D., Farach-Colton, M., Zito, J.: Two simplified algorithms for maintaining order in a list. In: Algorithms - ESA 2002, 10th Annual European Symposium, Rome, Italy, September 17-21, 2002, Proceedings. Lecture Notes in Computer Science, vol. 2461, pp. 152-164. Springer (2002). https://doi. org/10.1007/3-540-45749-6\_17
- 6. Breslauer, D., Italiano, G.F.: On suffix extensions in suffix trees. Theoretical Computer Science 457 , 27-34 (2012). https://doi.org/10.1016/J.TCS.2012.07.018
- 7. Breslauer, D., Italiano, G.F.: Near real-time suffix tree construction via the fringe marked ancestor problem. Journal of Discrete Algorithms 18 , 32-48 (2013). https: //doi.org/10.1016/J.JDA.2012.07.003

- 8. Feigenblat, G., Porat, E., Shiftan, A.: An improved query time for succinct dynamic dictionary matching. In: 25th Annual Symposium on Combinatorial Pattern Matching, CPM 2014, June 16-18, 2014. Moscow, Russia [1], pp. 120-129. https://doi.org/10.1007/978-3-319-07566-2\_13
- 10. Guo, P., Eades, P., Wirth, A., Zobel, J.: Exploiting new properties of string net frequency for efficient computation. In: 35th Annual Symposium on Combinatorial Pattern Matching, CPM 2024, June 25-27, 2024, Fukuoka, Japan. LIPIcs, vol. 296, pp. 16:1-16:16. Schloss Dagstuhl - Leibniz-Zentrum für Informatik (2024). https: //doi.org/10.4230/LIPICS.CPM.2024.16
- 9. Fujishige, Y., Tsujimaru, Y., Inenaga, S., Bannai, H., Takeda, M.: Linear-time computation of DAWGs, symmetric indexing structures, and MAWs for integer alphabets. Theoretical Computer Science 973 , 114093 (2023). https://doi.org/10. 1016/J.TCS.2023.114093
- 11. Gusfield, D.: Algorithms on Strings, Trees, and Sequences - Computer Science and Computational Biology. Cambridge University Press (1997). https://doi.org/10. 1017/CBO9780511574931
- 13. Larsson, N.J.: Most recent match queries in on-line suffix trees. In: 25th Annual Symposium on Combinatorial Pattern Matching, CPM 2014, June 16-18, 2014. Moscow, Russia [1], pp. 252-261. https://doi.org/10.1007/978-3-319-07566-2\_26
- 12. Inenaga, S., Takeda, M.: On-line linear-time construction of word suffix trees. In: 17th Annual Symposium on Combinatorial Pattern Matching, CPM 2006, July 5-7, 2006, Barcelona, Spain. Lecture Notes in Computer Science, vol. 4009, pp. 60-71. Springer (2006). https://doi.org/10.1007/11780441\_7
- 14. Lin, Y., Yu, M.: Extracting Chinese frequent strings without dictionary from a Chinese corpus and its applications. Journal of Information Science and Engineering 17 (5), 805-824 (2001), https://jise.iis.sinica.edu.tw/JISESearch/pages/View/ PaperView.jsf?keyId=86\_1308
- 16. McCreight, E.M.: A space-economical suffix tree construction algorithm. Journal of the ACM 23 (2), 262-272 (1976). https://doi.org/10.1145/321941.321946
- 15. Lin, Y., Yu, M.: The properties and further applications of Chinese frequent strings. International Journal of Computational Linguistics and Chinese Language Processing 9 (1) (2004), http://www.aclclp.org.tw/clclp/v9n1/v9n1a7.pdf
- 17. Moffat, A.: Implementing the PPM data compression scheme. IEEE Transactions on Communications 38 (11), 1917-1921 (1990). https://doi.org/10.1109/26.61469
- 19. Starikovskaya, T., Vildhøj, H.W.: A suffix tree or not a suffix tree? Journal of Discrete Algorithms 32 , 14-23 (2015). https://doi.org/10.1016/J.JDA.2015.01.005
- 18. Nakashima, K., Fujisato, N., Hendrian, D., Nakashima, Y., Yoshinaka, R., Inenaga, S., Bannai, H., Shinohara, A., Takeda, M.: Parameterized DAWGs: Efficient constructions and bidirectional pattern searches. Theoretical Computer Science 933 , 21-42 (2022). https://doi.org/10.1016/J.TCS.2022.09.008
- 20. Takagi, T., Inenaga, S., Arimura, H.: Fully-online construction of suffix trees for multiple texts. In: 27th Annual Symposium on Combinatorial Pattern Matching, CPM 2016, June 27-29, 2016, Tel Aviv, Israel. LIPIcs, vol. 54, pp. 22:1-22:13. Schloss Dagstuhl -Leibniz-Zentrum für Informatik (2016). https://doi.org/10. 4230/LIPICS.CPM.2016.22
- 22. Weiner, P.: Linear pattern matching algorithms. In: 14th Annual Symposium on Switching and Automata Theory, Iowa City, Iowa, USA, October 15-17, 1973. pp. 1-11. IEEE Computer Society (1973). https://doi.org/10.1109/SWAT.1973.13
- 21. Ukkonen, E.: On-line construction of suffix trees. Algorithmica 14 (3), 249-260 (1995). https://doi.org/10.1007/BF01206331
Peaker Guo Seeun William Umboh Anthony Wirth Justin Zobel
Online Computation of String Net Frequency
The net frequency (NF) of a string, of length $m$, in a text, of length $n$,
is the number of occurrences of the string in the text with unique left and
right extensions. Recently, Guo et al. [CPM 2024] showed that NF is
combinatorially interesting and how two key questions can be computed
efficiently in the offline setting. First, SINGLE-NF: reporting the NF of a
query string in an input text. Second, ALL-NF: reporting an occurrence and the
NF of each string of positive NF in an input text. For many applications,
however, facilitating these computations in an online manner is highly
desirable. We are the first to solve the above two problems in the online
setting, and we do so in optimal time, assuming, as is common, a constant-size
alphabet: SINGLE-NF in $O(m)$ time and ALL-NF in $O(n)$ time. Our results are
achieved by first designing new and simpler offline algorithms using suffix
trees, proving additional properties of NF, and exploiting Ukkonen's online
suffix tree construction algorithm and results on implicit node maintenance in
an implicit suffix tree by Breslauer and Italiano.