Find the Suffix Array of given String with no repeating character
Given a string str of size N, the task is to find the suffix array of the given string.
Note: A suffix array is a sorted array of all suffixes of a given string.
Examples:
Input: str = “prince”
Output: 4 5 2 3 0 1
Explanation: The suffixes are
0 prince 4 ce
1 rince Sort the suffixes 5 e
2 ince —————-> 2 ince
3 nce alphabetically 3 nce
4 ce 0 prince
5 e 1 rinceInput: str = “abcd”
Output: 0 1 2 3
Approach: The methods of suffix array finding for any string are discussed here. In this article, the focus is on finding suffix array for strings with no repeating character. It is a simple implementation based problem. Follow the steps mentioned below to solve the problem:
- Count occurrence of each character.
- Find prefix sum of it.
- Find start array by start[0] = 0, start[i+1] = prefix[i] for all i > 0 .
- Find start array containing the index of the substring (suffix) with starting character of the respective column.
Follow the illustration below for better understanding.
Illustration:
Consider string “prince”:
Given below is the suffix table
char a b c d e f g h i j k l m n o p q r s t u v w x y z count 0 0 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 prefix 0 0 1 1 2 2 2 2 3 3 3 3 3 4 4 5 5 6 6 6 6 6 6 6 6 6 start 0 0 0 1 1 2 2 2 2 3 3 3 3 3 4 4 5 5 6 6 6 6 6 6 6 6 For char ‘r’ start value is 5 .
Implies substring (suffix) starting with char ‘r’ i.e. “rince” has rank 5 .
Rank is position in suffix array. ( 1 “rince” ) implies 5th position in suffix array ), refer first table.
Similarly, start value of char ‘n’ is 3 . Implies ( 3 “nce” ) 3rd position in suffix array .
Below is the implementation of the above approach
C++
// C++ code to implement above approach #include <bits/stdc++.h> using namespace std; // Function to calculate the suffix array void suffixArray(string str, int N) { // arr[] is array to count // occurrence of each character int arr[30] = { 0 }; for ( int i = 0; i < N; i++) { arr[str[i] - 'a' ]++; } // Finding prefix count of character for ( int i = 1; i < 30; i++) { arr[i] = arr[i] + arr[i - 1]; } int start[30]; start[0] = 0; for ( int i = 0; i < 29; i++) { start[i + 1] = arr[i]; } int ans[N] = { 0 }; // Iterating string in reverse order for ( int i = N - 1; i >= 0; i--) { // Storing suffix array in ans[] ans[start[str[i] - 'a' ]] = i; } for ( int i = 0; i < N; i++) cout << ans[i] << " " ; } // Driver code int main() { string str = "prince" ; int N = str.length(); suffixArray(str, N); return 0; } |
Java
// Java program for the above approach import java.io.*; import java.lang.*; import java.util.*; class GFG { // Function to calculate the suffix array static void suffixArray(String str, int N) { // arr[] is array to count // occurrence of each character int arr[] = new int [ 30 ]; for ( int i = 0 ; i < N; i++) { arr[str.charAt(i) - 'a' ]++; } // Finding prefix count of character for ( int i = 1 ; i < 30 ; i++) { arr[i] = arr[i] + arr[i - 1 ]; } int start[] = new int [ 30 ]; start[ 0 ] = 0 ; for ( int i = 0 ; i < 29 ; i++) { start[i + 1 ] = arr[i]; } int ans[] = new int [N]; // Iterating string in reverse order for ( int i = N - 1 ; i >= 0 ; i--) { // Storing suffix array in ans[] ans[start[str.charAt(i) - 'a' ]] = i; } for ( int i = 0 ; i < N; i++) System.out.print(ans[i] + " " ); } // Driver code public static void main (String[] args) { String str = "prince" ; int N = str.length(); suffixArray(str, N); } } // This code is contributed by hrithikgarg03188 |
Python3
# Python code for the above approach # Function to calculate the suffix array def suffixArray( str , N): # arr[] is array to count # occurrence of each character arr = [ 0 ] * 30 for i in range (N): arr[ ord ( str [i]) - ord ( 'a' )] + = 1 # Finding prefix count of character for i in range ( 1 , 30 ): arr[i] = arr[i] + arr[i - 1 ] start = [ 0 ] * 30 start[ 0 ] = 0 for i in range ( 29 ): start[i + 1 ] = arr[i] ans = [ 0 ] * N # Iterating string in reverse order for i in range (N - 1 , 0 , - 1 ): # Storing suffix array in ans[] ans[start[ ord ( str [i]) - ord ( 'a' )]] = i for i in range (N): print (ans[i], end = " " ) # Driver code str = "prince" N = len ( str ) suffixArray( str , N) # This code is contributed by gfgking |
C#
// C# code to implement above approach using System; class GFG { // Function to calculate the suffix array static void suffixArray( string str, int N) { // arr[] is array to count // occurrence of each character int [] arr = new int [30]; for ( int i = 0; i < N; i++) { arr[str[i] - 'a' ]++; } // Finding prefix count of character for ( int i = 1; i < 30; i++) { arr[i] = arr[i] + arr[i - 1]; } int [] start = new int [30]; start[0] = 0; for ( int i = 0; i < 29; i++) { start[i + 1] = arr[i]; } int [] ans = new int [N]; // Iterating string in reverse order for ( int i = N - 1; i >= 0; i--) { // Storing suffix array in ans[] ans[start[str[i] - 'a' ]] = i; } for ( int i = 0; i < N; i++) { Console.Write(ans[i]); Console.Write( " " ); } } // Driver code public static int Main() { string str = "prince" ; int N = str.Length; suffixArray(str, N); return 0; } } // This code is contributed by Taranpreet |
Javascript
<script> // JavaScript code for the above approach // Function to calculate the suffix array function suffixArray(str, N) { // arr[] is array to count // occurrence of each character let arr = new Array(30).fill(0); for (let i = 0; i < N; i++) { arr[str[i].charCodeAt(0) - 'a' .charCodeAt(0)]++; } // Finding prefix count of character for (let i = 1; i < 30; i++) { arr[i] = arr[i] + arr[i - 1]; } let start = new Array(30) start[0] = 0; for (let i = 0; i < 29; i++) { start[i + 1] = arr[i]; } let ans = new Array(N).fill(0) // Iterating string in reverse order for (let i = N - 1; i >= 0; i--) { // Storing suffix array in ans[] ans[start[str[i].charCodeAt(0) - 'a' .charCodeAt(0)]] = i; } for (let i = 0; i < N; i++) document.write(ans[i] + " " ) } // Driver code let str = "prince" ; let N = str.length; suffixArray(str, N); // This code is contributed by Potta Lokesh </script> |
4 5 2 3 0 1
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...