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:
- Initialize an array arr[] of vectors of length 26 to store the indices of the characters present in the string and rank as 0.
- 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.
- Traverse each index stored in the array arr[] up to the characters which are smaller than the first character of the string S.
- 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.
- Now, after traversing, store all the substrings starting from the first character of S and sort those substrings in lexicographical order.
- Traverse the sorted substrings and compare each substring with the string S and increment the rank until substring equals to S is found.
- Print the value of rank + 1 to get the rank of the given string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int lexicographicRank(string s)
{
int n = s.length();
vector< int > alphaIndex[26];
for ( int i = 0; i < s.length(); i++) {
int x = s[i] - 'a' ;
alphaIndex[x].push_back(i);
}
int rank = 0;
for ( int i = 0; i < 26
&& 'a' + i < s[0];
i++) {
if (alphaIndex[i].size() > 0) {
for ( int j = 0;
j < alphaIndex[i].size(); j++) {
rank = rank
+ (n
- alphaIndex[i][j]);
}
}
}
vector<string> str;
for ( int i = 0;
i < alphaIndex[s[0] - 'a' ].size();
i++) {
string substring;
int j = alphaIndex[s[0] - 'a' ][i];
for (; j < n; j++) {
substring.push_back(s[j]);
str.push_back(substring);
}
}
sort(str.begin(), str.end());
for ( int i = 0; i < str.size(); i++) {
if (str[i] != s) {
rank++;
}
else {
break ;
}
}
return rank + 1;
}
int main()
{
string str = "enren" ;
cout << lexicographicRank(str);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int lexicographicRank( char []s)
{
int n = s.length;
Vector<Integer> []alphaIndex = new Vector[ 26 ];
for ( int i = 0 ; i < alphaIndex.length; i++)
alphaIndex[i] = new Vector<Integer>();
for ( int i = 0 ; i < s.length; i++)
{
int x = s[i] - 'a' ;
alphaIndex[x].add(i);
}
int rank = 0 ;
for ( int i = 0 ; i < 26 &&
'a' + i < s[ 0 ]; i++)
{
if (alphaIndex[i].size() > 0 )
{
for ( int j = 0 ;
j < alphaIndex[i].size();
j++)
{
rank = rank + (n - alphaIndex[i].get(j));
}
}
}
Vector<String> str = new Vector<String>();
for ( int i = 0 ;
i < alphaIndex[s[ 0 ] - 'a' ].size();
i++)
{
String subString = "" ;
int j = alphaIndex[s[ 0 ] - 'a' ].get(i);
for (; j < n; j++)
{
subString += (s[j]);
str.add(subString);
}
}
Collections.sort(str);
for ( int i = 0 ; i < str.size(); i++)
{
if (!str.get(i).equals(String.valueOf(s)))
{
rank++;
}
else
{
break ;
}
}
return rank + 1 ;
}
public static void main(String[] args)
{
String str = "enren" ;
System.out.print(lexicographicRank(str.toCharArray()));
}
}
|
Python3
def lexicographicRank(s):
n = len (s)
alphaIndex = [[] for i in range ( 26 )]
for i in range ( len (s)):
x = ord (s[i]) - ord ( 'a' )
alphaIndex[x].append(i)
rank = - 1
for i in range ( 26 ):
if ord ( 'a' ) + i > = ord (s[ 0 ]):
break
if len (alphaIndex[i]) > 0 :
for j in range ( len (alphaIndex[i])):
rank = rank + (n - alphaIndex[i][j])
strr = []
for i in range ( len (alphaIndex[ ord (s[ 0 ]) - ord ( 'a' )])):
substring = []
jj = alphaIndex[ ord (s[ 0 ]) - ord ( 'a' )][i]
for j in range (jj, n):
substring.append(s[j])
strr.append(substring)
strr = sorted (strr)
for i in range ( len (strr)):
if (strr[i] ! = s):
rank + = 1
else :
break
return rank + 1
if __name__ = = '__main__' :
strr = "enren"
print (lexicographicRank(strr))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int lexicographicRank( char []s)
{
int n = s.Length;
List< int > []alphaIndex = new List< int >[26];
for ( int i = 0; i < alphaIndex.Length; i++)
alphaIndex[i] = new List< int >();
for ( int i = 0; i < s.Length; i++)
{
int x = s[i] - 'a' ;
alphaIndex[x].Add(i);
}
int rank = 0;
for ( int i = 0; i < 26 &&
'a' + i < s[0]; i++)
{
if (alphaIndex[i].Count > 0)
{
for ( int j = 0;
j < alphaIndex[i].Count; j++)
{
rank = rank + (n - alphaIndex[i][j]);
}
}
}
List<String> str = new List<String>();
for ( int i = 0;
i < alphaIndex[s[0] - 'a' ].Count; i++)
{
String subString = "" ;
int j = alphaIndex[s[0] - 'a' ][i];
for (; j < n; j++)
{
subString += (s[j]);
str.Add(subString);
}
}
str.Sort();
for ( int i = 0; i < str.Count; i++)
{
if (!str[i].Equals(String.Join( "" , s)))
{
rank++;
}
else
{
break ;
}
}
return rank + 1;
}
public static void Main(String[] args)
{
String str = "enren" ;
Console.Write(lexicographicRank(str.ToCharArray()));
}
}
|
Javascript
<script>
function lexicographicRank(s)
{
var n = s.length;
var alphaIndex = Array.from(Array(26),
()=> new Array());
for ( var i = 0; i < s.length; i++) {
var x = s[i].charCodeAt(0) -
'a' .charCodeAt(0);
alphaIndex[x].push(i);
}
var rank = 0;
for ( var i = 0; i < 26
&& 'a' .charCodeAt(0) +
i < s[0].charCodeAt(0);
i++) {
if (alphaIndex[i].length > 0) {
for ( var j = 0;
j < alphaIndex[i].length; j++) {
rank = rank
+ (n
- alphaIndex[i][j]);
}
}
}
var str = [];
for ( var i = 0;
i < alphaIndex[s[0].charCodeAt(0) -
'a' .charCodeAt(0)].length;
i++) {
var substring = "" ;
var j = alphaIndex[s[0].charCodeAt(0) -
'a' .charCodeAt(0)][i];
for (; j < n; j++) {
substring+=(s[j]);
str.push(substring);
}
}
str.sort();
for ( var i = 0; i < str.length; i++) {
if (str[i] != s) {
rank++;
}
else {
break ;
}
}
return rank + 1;
}
var str = "enren" ;
document.write( lexicographicRank(str));
</script>
|
Time Complexity: O(N3)
Auxiliary Space: O(N)
Last Updated :
14 Sep, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...