Related Articles

# Lexicographic rank of a string among all its substrings

• Difficulty Level : Expert
• Last Updated : 14 Sep, 2021

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 substring``int` `lexicographicRank(string s)``{``    ``// Length of string``    ``int` `n = s.length();` `    ``vector<``int``> 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 Code``int` `main()``{``    ``// Given string``    ``string str = ``"enren"``;` `    ``// Function Call``    ``cout << lexicographicRank(str);` `    ``return` `0;``}`

## Java

 `// Java program for``// the above approach``import` `java.util.*;``class` `GFG{` `// Function to find lexicographic rank``// of String among all its subString``static` `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 Code``public` `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 substring``def` `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 Code``if` `__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 approach``using` `System;``using` `System.Collections.Generic;``class` `GFG{` `// Function to find lexicographic rank``// of String among all its subString``static` `int` `lexicographicRank(``char` `[]s)``{``  ``// Length of String``  ``int` `n = s.Length;` `  ``List<``int``> []alphaIndex = ``new` `List<``int``>[26];``  ``for` `(``int` `i = 0; i < alphaIndex.Length; i++)``    ``alphaIndex[i] = ``new` `List<``int``>();` `  ``// 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 Code``public` `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)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up