# Lexicographic rank of a string among all its substrings

Given string str, the task is to find the rank of the given string among all its substrings arranged lexicographically.

Examples:

Input: S = “enren”
Output: 7
Explanation:
All the possible substrings in the sorted order are {“e”, “e”, “en”, “en”, “enr”, “enre”, “enren”, “n”, “n”, “nr”, “nre”, “nren”, “r”, “re”, “ren”}.
Therefore, the rank of the given string “enren” is 7.

Input: S = “geeks”
Output: 12
Explanation:
All possible substrings in the sorted order are {“e”, “e”, “ee”, “eek”, “eeks”, “ek”, “eks”, “g”, “ge”, “gee”, “geek”, “geeks”, “k”, “ks”, “s”}.
Therefore, the rank of the given string “geeks” is 12.

Approach: Follow the steps below to solve the problem:

1. Initialize an array arr[] of vectors of length 26 to store the indices of the characters present in the string and rank as 0.
2. Store the indices of each character. Indices of a will be stored in arr[0], for b, arr[1] will store all its indices, and so on.
3. Traverse each index stored in the array arr[] up to the characters which are smaller than the first character of the string S.
4. For each index i, total substrings starting from that index is N – i. Add N – i to rank as all characters with these indices are smaller.
5. Now, after traversing, store all the substrings starting from the first character of S and sort those substrings in lexicographical order.
6. Traverse the sorted substrings and compare each substring with the string S and increment the rank until substring equals to S is found.
7. Print the value of rank + 1 to get the rank of the given string.

Below is the implementation of the above approach:

## C++

 // C++ program for the above approach #include using namespace std; // Function to find lexicographic rank// of string among all its substringint lexicographicRank(string s){    // Length of string    int n = s.length();     vector alphaIndex[26];     // Traverse the given string    // and store the indices of    // each character    for (int i = 0; i < s.length(); i++) {         // Extract the index        int x = s[i] - 'a';         // Store it in the vector        alphaIndex[x].push_back(i);    }     // Traverse the alphaIndex array    // lesser than the index of first    // character of given string    int rank = 0;     for (int i = 0; i < 26                    && 'a' + i < s[0];         i++) {         // If alphaIndex[i] size exceeds 0        if (alphaIndex[i].size() > 0) {             // Traverse over the indices            for (int j = 0;                 j < alphaIndex[i].size(); j++) {                 // Add count of substring                // equal to n - alphaIndex[i][j]                rank = rank                       + (n                          - alphaIndex[i][j]);            }        }    }     vector str;     for (int i = 0;         i < alphaIndex[s[0] - 'a'].size();         i++) {         // Store all substrings in a vector        // str starting with the first        // character of the given string        string substring;         int j = alphaIndex[s[0] - 'a'][i];         for (; j < n; j++) {             // Insert the current            // character to substring            substring.push_back(s[j]);             // Store the substring formed            str.push_back(substring);        }    }     // Sort the substring in the    // lexicographical order    sort(str.begin(), str.end());     // Find the rank of given string    for (int i = 0; i < str.size(); i++) {         if (str[i] != s) {             // increase the rank until            // the given string is same            rank++;        }         // If substring is same as        // the given string        else {            break;        }    }     // Add 1 to rank of    // the given string    return rank + 1;} // Driver Codeint main(){    // Given string    string str = "enren";     // Function Call    cout << lexicographicRank(str);     return 0;}

## Java

 // Java program for // the above approachimport java.util.*;class GFG{ // Function to find lexicographic rank// of String among all its subStringstatic int lexicographicRank(char []s){  // Length of String  int n = s.length;   Vector []alphaIndex = new Vector[26];  for (int i = 0; i < alphaIndex.length; i++)    alphaIndex[i] = new Vector();     // Traverse the given String  // and store the indices of  // each character  for (int i = 0; i < s.length; i++)   {    // Extract the index    int x = s[i] - 'a';     // Store it in the vector    alphaIndex[x].add(i);  }   // Traverse the alphaIndex array  // lesser than the index of first  // character of given String  int rank = 0;   for (int i = 0; i < 26 &&            'a' + i < s[0]; i++)   {    // If alphaIndex[i] size exceeds 0    if (alphaIndex[i].size() > 0)     {      // Traverse over the indices      for (int j = 0;               j < alphaIndex[i].size();                j++)       {        // Add count of subString        // equal to n - alphaIndex[i][j]        rank = rank + (n - alphaIndex[i].get(j));      }    }  }   Vector str = new Vector();   for (int i = 0;           i < alphaIndex[s[0] - 'a'].size();           i++)   {    // Store all subStrings in a vector    // str starting with the first    // character of the given String    String subString = "";     int j = alphaIndex[s[0] - 'a'].get(i);     for (; j < n; j++)     {      // Insert the current      // character to subString      subString += (s[j]);       // Store the subString formed      str.add(subString);    }  }   // Sort the subString in the  // lexicographical order  Collections.sort(str);   // Find the rank of given String  for (int i = 0; i < str.size(); i++)   {    if (!str.get(i).equals(String.valueOf(s)))     {      // increase the rank until      // the given String is same      rank++;    }     // If subString is same as    // the given String    else    {      break;    }  }   // Add 1 to rank of  // the given String  return rank + 1;} // Driver Codepublic static void main(String[] args){  // Given String  String str = "enren";   // Function Call  System.out.print(lexicographicRank(str.toCharArray()));}} // This code is contributed by shikhasingrajput

## Python3

 # Python3 program for the above approach # Function to find lexicographic rank# of among all its substringdef lexicographicRank(s):         # Length of string    n = len(s)     alphaIndex = [[] for i in range(26)]     # Traverse the given string    # and store the indices of    # each character    for i in range(len(s)):         # Extract the index        x = ord(s[i]) - ord('a')         # Store it in the vector        alphaIndex[x].append(i)     # Traverse the alphaIndex array    # lesser than the index of first    # character of given string    rank = -1     for i in range(26):        if ord('a') + i >= ord(s[0]):            break         # If alphaIndex[i] size exceeds 0        if len(alphaIndex[i]) > 0:             # Traverse over the indices            for j in range(len(alphaIndex[i])):                 # Add count of substring                # equal to n - alphaIndex[i][j]                rank = rank + (n - alphaIndex[i][j])                     # print(rank)    strr = []     for i in range(len(alphaIndex[ord(s[0]) - ord('a')])):         # Store all substrings in a vector        # strr starting with the first        # character of the given string        substring = []         jj = alphaIndex[ord(s[0]) - ord('a')][i]         for j in range(jj, n):             # Insert the current            # character to substring            substring.append(s[j])             # Store the subformed            strr.append(substring)     # Sort the substring in the    # lexicographical order    strr = sorted(strr)     # Find the rank of given string    for i in range(len(strr)):        if (strr[i] != s):             # Increase the rank until            # the given is same            rank += 1         # If substring is same as        # the given string        else:            break     # Add 1 to rank of    # the given string    return rank + 1 # Driver Codeif __name__ == '__main__':         # Given string    strr = "enren"     # Function call    print(lexicographicRank(strr)) # This code is contributed by mohit kumar 29

## C#

 // C# program for // the above approachusing System;using System.Collections.Generic;class GFG{ // Function to find lexicographic rank// of String among all its subStringstatic int lexicographicRank(char []s){  // Length of String  int n = s.Length;   List []alphaIndex = new List[26];  for (int i = 0; i < alphaIndex.Length; i++)    alphaIndex[i] = new List();   // Traverse the given String  // and store the indices of  // each character  for (int i = 0; i < s.Length; i++)   {    // Extract the index    int x = s[i] - 'a';     // Store it in the vector    alphaIndex[x].Add(i);  }   // Traverse the alphaIndex array  // lesser than the index of first  // character of given String  int rank = 0;   for (int i = 0; i < 26 &&            'a' + i < s[0]; i++)   {    // If alphaIndex[i] size exceeds 0    if (alphaIndex[i].Count > 0)     {      // Traverse over the indices      for (int j = 0;               j < alphaIndex[i].Count; j++)       {        // Add count of subString        // equal to n - alphaIndex[i,j]        rank = rank + (n - alphaIndex[i][j]);      }    }  }   List str = new List();   for (int i = 0;           i < alphaIndex[s[0] - 'a'].Count; i++)   {    // Store all subStrings in a vector    // str starting with the first    // character of the given String    String subString = "";     int j = alphaIndex[s[0] - 'a'][i];     for (; j < n; j++)     {      // Insert the current      // character to subString      subString += (s[j]);       // Store the subString formed      str.Add(subString);    }  }   // Sort the subString in the  // lexicographical order  str.Sort();   // Find the rank of given String  for (int i = 0; i < str.Count; i++)   {    if (!str[i].Equals(String.Join("", s)))     {      // increase the rank until      // the given String is same      rank++;    }     // If subString is same as    // the given String    else    {      break;    }  }   // Add 1 to rank of  // the given String  return rank + 1;} // Driver Codepublic static void Main(String[] args){  // Given String  String str = "enren";   // Function Call  Console.Write(lexicographicRank(str.ToCharArray()));}} // This code is contributed by 29AjayKumar

## Javascript



Output:
7

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

Previous
Next