Open In App

# Count of distinct substrings of a string using Suffix Trie

Given a string of length n of lowercase alphabet characters, we need to count total number of distinct substrings of this string. Examples:

```Input  : str = “ababa”
Output : 10
Total number of distinct substring are 10, which are,
"", "a", "b", "ab", "ba", "aba", "bab", "abab", "baba"
and "ababa"```

The idea is create a Trie of all suffixes of given string. Once the Trie is constricted, our answer is total number of nodes in the constructed Trie. For example below diagram represent Trie of all suffixes for “ababa”. Total number of nodes is 10 which is our answer.

How does this work?

• Each root to node path of a Trie represents a prefix of words present in Trie. Here we words are suffixes. So each node represents a prefix of suffixes.
• Every substring of a string “str” is a prefix of a suffix of “str”.

Below is implementation based on above idea.

## C++

 `// A C++ program to find the count of distinct substring``// of a string using trie data structure``#include ``#define MAX_CHAR 26``using` `namespace` `std;`` ` `// A Suffix Trie (A Trie of all suffixes) Node``class` `SuffixTrieNode``{``public``:``    ``SuffixTrieNode *children[MAX_CHAR];``    ``SuffixTrieNode() ``// Constructor``    ``{``        ``// Initialize all child pointers as NULL``        ``for` `(``int` `i = 0; i < MAX_CHAR; i++)``          ``children[i] = NULL;``    ``}`` ` `    ``// A recursive function to insert a suffix of the s``    ``// in subtree rooted with this node``    ``void` `insertSuffix(string suffix);``};`` ` `// A Trie of all suffixes``class` `SuffixTrie``{``    ``SuffixTrieNode *root;``    ``int` `_countNodesInTrie(SuffixTrieNode *);``public``:``    ``// Constructor (Builds a trie of suffies of the given text)``    ``SuffixTrie(string s)``    ``{``        ``root = ``new` `SuffixTrieNode();`` ` `        ``// Consider all suffixes of given string and insert``        ``// them into the Suffix Trie using recursive function``        ``// insertSuffix() in SuffixTrieNode class``        ``for` `(``int` `i = 0; i < s.length(); i++)``            ``root->insertSuffix(s.substr(i));``    ``}`` ` `    ``//  method to count total nodes in suffix trie``    ``int` `countNodesInTrie() { ``return` `_countNodesInTrie(root); }``};`` ` `// A recursive function to insert a suffix of the s in``// subtree rooted with this node``void` `SuffixTrieNode::insertSuffix(string s)``{``    ``// If string has more characters``    ``if` `(s.length() > 0)``    ``{``        ``// Find the first character and convert it``        ``// into 0-25 range.``        ``char` `cIndex = s.at(0) - ``'a'``;`` ` `        ``// If there is no edge for this character,``        ``// add a new edge``        ``if` `(children[cIndex] == NULL)``            ``children[cIndex] = ``new` `SuffixTrieNode();`` ` `        ``// Recur for next suffix``        ``children[cIndex]->insertSuffix(s.substr(1));``    ``}``}`` ` `// A recursive function to count nodes in trie``int` `SuffixTrie::_countNodesInTrie(SuffixTrieNode* node)``{``    ``// If all characters of pattern have been processed,``    ``if` `(node == NULL)``        ``return` `0;`` ` `    ``int` `count = 0;``    ``for` `(``int` `i = 0; i < MAX_CHAR; i++)``    ``{``        ``// if children is not NULL then find count``        ``// of all nodes in this subtrie``        ``if` `(node->children[i] != NULL)``            ``count += _countNodesInTrie(node->children[i]);``    ``}`` ` `    ``// return count of nodes of subtrie and plus``    ``// 1 because of node's own count``    ``return` `(1 + count);``}`` ` `// Returns count of distinct substrings of str``int` `countDistinctSubstring(string str)``{``    ``// Construct a Trie of all suffixes``    ``SuffixTrie sTrie(str);`` ` `    ``// Return count of nodes in Trie of Suffixes``    ``return` `sTrie.countNodesInTrie();``}`` ` `// Driver program to test above function``int` `main()``{``    ``string str = ``"ababa"``;``    ``cout << ``"Count of distinct substrings is "``         ``<< countDistinctSubstring(str);``    ``return` `0;``}`

## Java

 `// A Java program to find the count of distinct substring``// of a string using trie data structure``public` `class` `Suffix ``{``    ``// A Suffix Trie (A Trie of all suffixes) Node``    ``static` `class` `SuffixTrieNode``    ``{``        ``static` `final` `int` `MAX_CHAR = ``26``;``        ``SuffixTrieNode[] children = ``new` `SuffixTrieNode[MAX_CHAR];`` ` `        ``SuffixTrieNode() ``// Constructor``        ``{``            ``// Initialize all child pointers as NULL``            ``for` `(``int` `i = ``0``; i < MAX_CHAR; i++)``                ``children[i] = ``null``;``        ``}`` ` `        ``// A recursive function to insert a suffix of the s in``        ``// subtree rooted with this node``        ``void` `insertSuffix(String s) ``        ``{``            ``// If string has more characters``            ``if` `(s.length() > ``0``) ``            ``{``                ``// Find the first character and convert it``                ``// into 0-25 range.``                ``char` `cIndex = (``char``) (s.charAt(``0``) - ``'a'``);`` ` `                ``// If there is no edge for this character,``                ``// add a new edge``                ``if` `(children[cIndex] == ``null``)``                    ``children[cIndex] = ``new` `SuffixTrieNode();`` ` `                ``// Recur for next suffix``                ``children[cIndex].insertSuffix(s.substring(``1``));``                ``}``        ``}``    ``}``     ` `    ``// A Trie of all suffixes``    ``static` `class` `Suffix_trie ``    ``{``        ``static` `final` `int` `MAX_CHAR = ``26``;``        ``SuffixTrieNode root;`` ` `        ``// Constructor (Builds a trie of suffies of the given text)``        ``Suffix_trie(String s) {``            ``root = ``new` `SuffixTrieNode();`` ` `            ``// Consider all suffixes of given string and insert``            ``// them into the Suffix Trie using recursive function``            ``// insertSuffix() in SuffixTrieNode class``            ``for` `(``int` `i = ``0``; i < s.length(); i++)``                ``root.insertSuffix(s.substring(i));``        ``}`` ` `        ``// A recursive function to count nodes in trie``        ``int` `_countNodesInTrie(SuffixTrieNode node) ``        ``{``            ``// If all characters of pattern have been processed,``            ``if` `(node == ``null``)``                ``return` `0``;`` ` `            ``int` `count = ``0``;``            ``for` `(``int` `i = ``0``; i < MAX_CHAR; i++) {`` ` `                ``// if children is not NULL then find count``                ``// of all nodes in this subtrie``                ``if` `(node.children[i] != ``null``)``                    ``count += _countNodesInTrie(node.children[i]);``            ``}`` ` `            ``// return count of nodes of subtrie and plus``            ``// 1 because of node's own count``            ``return` `(``1` `+ count);``        ``}`` ` `        ``// method to count total nodes in suffix trie``        ``int` `countNodesInTrie() ``        ``{``            ``return` `_countNodesInTrie(root);``        ``}`` ` `    ``} `` ` `    ``// Returns count of distinct substrings of str``    ``static` `int` `countDistinctSubstring(String str)``    ``{``        ``// Construct a Trie of all suffixes``        ``Suffix_trie sTrie = ``new` `Suffix_trie(str);`` ` `        ``// Return count of nodes in Trie of Suffixes``        ``return` `sTrie.countNodesInTrie();``    ``}`` ` `    ``// Driver program to test above function``    ``public` `static` `void` `main(String args[]) ``    ``{``        ``String str = ``"ababa"``;``        ``System.out.println(``"Count of distinct substrings is "``                ``+ countDistinctSubstring(str));``         ` `    ``}``}``// This code is contributed by Sumit Ghosh`

## Python3

 `# Python program to find the count of distinct substring``# of a string using trie data structure`` ` `# A Suffix Trie (A Trie of all suffixes) Node``class` `SuffixTrieNode:``    ``def` `__init__(``self``):``        ``# Initialize all child pointers as NULL``        ``self``.children ``=` `[``None``] ``*` `26``     ` `    ``# A recursive function to insert a suffix of the s in``    ``# subtree rooted with this node``    ``def` `insert_suffix(``self``, suffix):``        ``# If string has more characters``        ``if` `suffix:``            ``# Find the first character and convert it``            ``# into 0-25 range.``            ``c_index ``=` `ord``(suffix[``0``]) ``-` `ord``(``'a'``)``            ``# If there is no edge for this character,``            ``# add a new edge``            ``if` `not` `self``.children[c_index]:``                ``self``.children[c_index] ``=` `SuffixTrieNode()``            ``# Recur for next suffix``            ``self``.children[c_index].insert_suffix(suffix[``1``:])`` ` `# A Trie of all suffixes``class` `SuffixTrie:``    ``def` `__init__(``self``, s):``        ``# Constructor (Builds a trie of suffies of the given text)``        ``self``.root ``=` `SuffixTrieNode()``        ``for` `i ``in` `range``(``len``(s)):``            ``# Consider all suffixes of given string and insert``            ``# them into the Suffix Trie using recursive function``            ``# insertSuffix() in SuffixTrieNode class``            ``self``.root.insert_suffix(s[i:])``     ` `    ``# method to count total nodes in suffix trie``    ``def` `countNodesInTrie(``self``):``        ``return` `self``._countNodesInTrie(``self``.root)``     ` `    ``def` `_countNodesInTrie(``self``, node):``        ``# If all characters of pattern have been processed,``        ``if` `node ``is` `None``:``            ``return` `0``        ``count ``=` `0``        ``for` `i ``in` `range``(``26``):``            ``# if children is not NULL then find count``            ``# of all nodes in this subtrie``            ``if` `node.children[i]:``                ``count ``+``=` `self``._countNodesInTrie(node.children[i])``        ``# return count of nodes of subtrie and plus``        ``# 1 because of node's own count``        ``return` `count ``+` `1`` ` `# Returns count of distinct substrings of str``def` `countDistinctSubstring(``str``):``    ``# Construct a Trie of all suffixes``    ``s_trie ``=` `SuffixTrie(``str``)``    ``# Return count of nodes in Trie of Suffixes``    ``return` `s_trie.countNodesInTrie()`` ` `# Driver program to test above function``if` `__name__ ``=``=` `'__main__'``:``    ``str` `=` `"ababa"``    ``print``(``"Count of distinct substrings is"``, countDistinctSubstring(``str``))`` ` `# This code is contributed by Aman Kumar.`

## C#

 `// C# program to find the count of distinct substring``// of a string using trie data structure``using` `System;`` ` `public` `class` `Suffix ``{``    ``// A Suffix Trie (A Trie of all suffixes) Node``    ``public` `class` `SuffixTrieNode``    ``{``        ``static` `readonly` `int` `MAX_CHAR = 26;``        ``public` `SuffixTrieNode[] children = ``new` `SuffixTrieNode[MAX_CHAR];`` ` `        ``public` `SuffixTrieNode() ``// Constructor``        ``{``            ``// Initialize all child pointers as NULL``            ``for` `(``int` `i = 0; i < MAX_CHAR; i++)``                ``children[i] = ``null``;``        ``}`` ` `        ``// A recursive function to insert a suffix of the s in``        ``// subtree rooted with this node``        ``public` `void` `insertSuffix(String s) ``        ``{``            ``// If string has more characters``            ``if` `(s.Length > 0) ``            ``{``                ``// Find the first character and convert it``                ``// into 0-25 range.``                ``char` `cIndex = (``char``) (s[0] - ``'a'``);`` ` `                ``// If there is no edge for this character,``                ``// add a new edge``                ``if` `(children[cIndex] == ``null``)``                    ``children[cIndex] = ``new` `SuffixTrieNode();`` ` `                ``// Recur for next suffix``                ``children[cIndex].insertSuffix(s.Substring(1));``                ``}``        ``}``    ``}``     ` `    ``// A Trie of all suffixes``    ``public` `class` `Suffix_trie ``    ``{``        ``static` `readonly` `int` `MAX_CHAR = 26;``        ``public` `SuffixTrieNode root;`` ` `        ``// Constructor (Builds a trie of suffies of the given text)``        ``public` `Suffix_trie(String s) ``        ``{``            ``root = ``new` `SuffixTrieNode();`` ` `            ``// Consider all suffixes of given string and insert``            ``// them into the Suffix Trie using recursive function``            ``// insertSuffix() in SuffixTrieNode class``            ``for` `(``int` `i = 0; i < s.Length; i++)``                ``root.insertSuffix(s.Substring(i));``        ``}`` ` `        ``// A recursive function to count nodes in trie``        ``public` `int` `_countNodesInTrie(SuffixTrieNode node) ``        ``{``            ``// If all characters of pattern have been processed,``            ``if` `(node == ``null``)``                ``return` `0;`` ` `            ``int` `count = 0;``            ``for` `(``int` `i = 0; i < MAX_CHAR; i++) ``            ``{`` ` `                ``// if children is not NULL then find count``                ``// of all nodes in this subtrie``                ``if` `(node.children[i] != ``null``)``                    ``count += _countNodesInTrie(node.children[i]);``            ``}`` ` `            ``// return count of nodes of subtrie and plus``            ``// 1 because of node's own count``            ``return` `(1 + count);``        ``}`` ` `        ``// method to count total nodes in suffix trie``        ``public` `int` `countNodesInTrie() ``        ``{``            ``return` `_countNodesInTrie(root);``        ``}`` ` `    ``} `` ` `    ``// Returns count of distinct substrings of str``    ``static` `int` `countDistinctSubstring(String str)``    ``{``        ``// Construct a Trie of all suffixes``        ``Suffix_trie sTrie = ``new` `Suffix_trie(str);`` ` `        ``// Return count of nodes in Trie of Suffixes``        ``return` `sTrie.countNodesInTrie();``    ``}`` ` `    ``// Driver program to test above function``    ``public` `static` `void` `Main(String []args) ``    ``{``        ``String str = ``"ababa"``;``        ``Console.WriteLine(``"Count of distinct substrings is "``                ``+ countDistinctSubstring(str));``         ` `    ``}``}`` ` `// This code contributed by Rajput-Ji`

## Javascript

 `// A Javascript program to find the count of distinct substring``// of a string using trie data structure``// A Suffix Trie (A Trie of all suffixes) Node``class SuffixTrieNode {``    ``constructor() {``        ``// Initialize all child pointers as null``        ``this``.children = ``new` `Array(26).fill(``null``);``    ``}`` ` `    ``// A recursive function to insert a suffix of the s in``    ``// subtree rooted with this node``    ``insertSuffix(suffix) {``     ` `        ``// If string has more characters``        ``if` `(suffix.length > 0) {``            ``// Find the first character and convert it``            ``// into 0-25 range.``            ``const cIndex = suffix.charCodeAt(0) - ``'a'``.charCodeAt(0);``            ``// If there is no edge for this character,``            ``// add a new edge``            ``if` `(!``this``.children[cIndex]) {``                ``this``.children[cIndex] = ``new` `SuffixTrieNode();``            ``}``            ``// Recur for next suffix``            ``this``.children[cIndex].insertSuffix(suffix.slice(1));``        ``}``    ``}``}`` ` `// A Trie of all suffixes``class SuffixTrie {``    ``constructor(s) {``        ``// Constructor (Builds a trie of suffies of the given text)``        ``this``.root = ``new` `SuffixTrieNode();``        ``for` `(let i = 0; i < s.length; i++) {``         ` `            ``// Consider all suffixes of given string and insert``            ``// them into the Suffix Trie using recursive function``            ``// insertSuffix() in SuffixTrieNode class``            ``this``.root.insertSuffix(s.slice(i));``        ``}``    ``}`` ` `    ``// method to count total nodes in suffix trie``    ``countNodesInTrie() {``        ``return` `this``._countNodesInTrie(``this``.root);``    ``}`` ` `    ``_countNodesInTrie(node) {``        ``// If all characters of pattern have been processed,``        ``if` `(node === ``null``) {``            ``return` `0;``        ``}``        ``let count = 0;``        ``for` `(let i = 0; i < 26; i++) {``         ` `            ``// if children is not null then find count``            ``// of all nodes in this subtrie``            ``if` `(node.children[i]) {``                ``count += ``this``._countNodesInTrie(node.children[i]);``            ``}``        ``}``         ` `        ``// return count of nodes of subtrie and plus``        ``// 1 because of node's own count``        ``return` `count + 1;``    ``}``}`` ` `// Returns count of distinct substrings of str``function` `countDistinctSubstring(str) {`` ` `    ``// Construct a Trie of all suffixes``    ``const sTrie = ``new` `SuffixTrie(str);``     ` `    ``// Return count of nodes in Trie of Suffixes``    ``return` `sTrie.countNodesInTrie();``}`` ` `// Driver program to test above function``const str = 'ababa``';``console.log('``Count of distinct substrings is', countDistinctSubstring(str));`

Output

`Count of distinct substrings is 10`

Time Complexity: O(n2), where n is the length of string.
Auxiliary Space: O(n)

We will soon be discussing Suffix Array and Suffix Tree based approaches for this problem. This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.