Open In App

Find the Suffix Array of given String with no repeating character

Last Updated : 24 Feb, 2022
Comments
Improve
Suggest changes
Like Article
Like
Report

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 rince

Input: 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 

charabcdefghijklmnopqrstuvwxyz
count00101000100001010100000000
prefix00112222333334455666666666
start00011222233333445566666666

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>

 
 


Output
4 5 2 3 0 1 


 

Time Complexity: O(N)
Auxiliary Space: O(N)


 


Next Article
Practice Tags :

Similar Reads