Open In App

Lexicographic rank of a String

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given a string str, find its rank among all its permutations when sorted lexicographically.

Note: The characters a string are all unique.

Examples:

Input: str = “acb”
Output: 2
Explanation: If all the permutations of the string are arranged lexicographically they will be “abc”, “acb”, “bac”, “bca”, “cab”, “cba”. From here it can be clearly that the rank of str is 2.

Input: str = “string”
Output: 598

Input: str[] = “cba”
Output: Rank = 6

Recommended Practice

Naive Approach: One simple solution is to generate all the permutations in lexicographic order and store the rank of the current string. After generating a permutation, check if the generated permutation is the same as the given string and return the rank of str.

Algorithm

Define a function to calculate the factorial of a given number using recursion.
fact(n):
if n <= 1:
return 1
return n * fact(n - 1)

Define a function to calculate the rank of a given string in lexicographic permutation order.
findRank(str):
Calculate the length of the input string

Initialize the rank as 1
Loop through each character of the string
Initialize a variable to count the number of characters less than str[i]
Loop through the characters after str[i]
Update the rank based on the count of characters less than str[i]
multiplied by the factorial of the number of remaining characters
Return the final rank of the input string
Define the main function.





C++




#include <bits/stdc++.h>
using namespace std;
 
// Define a function to calculate the factorial of a given number using recursion
int fact(int n) {
    // Base case: if n is 0 or 1, return 1
    if(n <= 1) {
        return 1;
    }
    // Recursive case: return n times the factorial of n-1
    return n * fact(n - 1);
}
 
// Define a function to calculate the rank of a given string in lexicographic permutation order
int findRank(string str) {
    // Calculate the length of the input string
    int n = str.length();
    // Initialize the rank as 1
    int rank = 1;
 
    // Loop through each character of the string
    for(int i = 0; i < n; i++) {
        // Initialize a variable to count the number of characters less than str[i]
        int count = 0;
 
        // Loop through the characters after str[i]
        for(int j = i + 1; j < n; j++) {
            // If str[i] is greater than str[j], increment the count variable
            if(str[i] > str[j]) {
                count++;
            }
        }
 
        // Update the rank based on the count of characters less than str[i]
        // multiplied by the factorial of the number of remaining characters
        rank += count * fact(n - i - 1);
    }
 
    // Return the final rank of the input string
    return rank;
}
 
// Define the main function
int main() {
    // Define a test string
    string str = "string";
    // Call the findRank function on the test string and print the result
    cout << findRank(str) << endl;
    // Return 0 to indicate successful program completion
    return 0;
}


Java




import java.util.Arrays;
 
public class LexicographicRank {
 
    // Define a function to calculate the factorial of a
    // given number using recursion
    static int fact(int n)
    {
        // Base case: if n is 0 or 1, return 1
        if (n <= 1) {
            return 1;
        }
        // Recursive case: return n times the factorial of
        // n-1
        return n * fact(n - 1);
    }
 
    // Define a function to calculate the rank of a given
    // string in lexicographic permutation order
    static int findRank(String str)
    {
        // Calculate the length of the input string
        int n = str.length();
        // Initialize the rank as 1
        int rank = 1;
 
        // Loop through each character of the string
        for (int i = 0; i < n; i++) {
            // Initialize a variable to count the number of
            // characters less than str.charAt(i)
            int count = 0;
 
            // Loop through the characters after
            // str.charAt(i)
            for (int j = i + 1; j < n; j++) {
                // If str.charAt(i) is greater than
                // str.charAt(j), increment the count
                // variable
                if (str.charAt(i) > str.charAt(j)) {
                    count++;
                }
            }
 
            // Update the rank based on the count of
            // characters less than str.charAt(i) multiplied
            // by the factorial of the number of remaining
            // characters
            rank += count * fact(n - i - 1);
        }
 
        // Return the final rank of the input string
        return rank;
    }
 
    // Define the main function
    public static void main(String[] args)
    {
        // Define a test string
        String str = "string";
        // Call the findRank function on the test string and
        // print the result
        System.out.println(findRank(str));
    }
}


Python3




# Define a function to calculate the factorial of a given number using recursion
def fact(n):
    # Base case: if n is 0 or 1, return 1
    if n <= 1:
        return 1
    # Recursive case: return n times the factorial of n-1
    return n * fact(n-1)
 
# Define a function to calculate the rank of a given string in lexicographic permutation order
def findRank(s):
    # Calculate the length of the input string
    n = len(s)
    # Initialize the rank as 1
    rank = 1
 
    # Loop through each character of the string
    for i in range(n):
        # Initialize a variable to count the number of characters less than s[i]
        count = 0
 
        # Loop through the characters after s[i]
        for j in range(i+1, n):
            # If s[i] is greater than s[j], increment the count variable
            if s[i] > s[j]:
                count += 1
 
        # Update the rank based on the count of characters less than s[i]
        # multiplied by the factorial of the number of remaining characters
        rank += count * fact(n-i-1)
 
    # Return the final rank of the input string
    return rank
 
# Define the main function
def main():
    # Define a test string
    s = "string"
    # Call the findRank function on the test string and print the result
    print(findRank(s))
    # Return 0 to indicate successful program completion
    return 0
 
# Call the main function
main()


C#




using System;
 
class Program {
    // Define a function to calculate the factorial of a
    // given number using recursion
    static int Fact(int n)
    {
        // Base case: if n is 0 or 1, return 1
        if (n <= 1) {
            return 1;
        }
        // Recursive case: return n times the factorial of
        // n-1
        return n * Fact(n - 1);
    }
 
    // Define a function to calculate the rank of a given
    // string in lexicographic permutation order
    static int FindRank(string str)
    {
        // Calculate the length of the input string
        int n = str.Length;
        // Initialize the rank as 1
        int rank = 1;
 
        // Loop through each character of the string
        for (int i = 0; i < n; i++) {
            // Initialize a variable to count the number of
            // characters less than str[i]
            int count = 0;
 
            // Loop through the characters after str[i]
            for (int j = i + 1; j < n; j++) {
                // If str[i] is greater than str[j],
                // increment the count variable
                if (str[i] > str[j]) {
                    count++;
                }
            }
 
            // Update the rank based on the count of
            // characters less than str[i] multiplied by the
            // factorial of the number of remaining
            // characters
            rank += count * Fact(n - i - 1);
        }
 
        // Return the final rank of the input string
        return rank;
    }
 
    // Define the main function
    static void Main(string[] args)
    {
        // Define a test string
        string str = "string";
        // Call the FindRank function on the test string and
        // print the result
        Console.WriteLine(FindRank(str));
    }
}


Javascript




// Define a function to calculate the factorial of a given number using recursion
function fact(n) {
    // Base case: if n is 0 or 1, return 1
    if (n <= 1) {
        return 1;
    }
    // Recursive case: return n times the factorial of n-1
    return n * fact(n - 1);
}
 
// Define a function to calculate the rank of a given string in lexicographic permutation order
function findRank(str) {
    // Calculate the length of the input string
    const n = str.length;
    // Initialize the rank as 1
    let rank = 1;
 
    // Loop through each character of the string
    for (let i = 0; i < n; i++) {
        // Initialize a variable to count the number of characters less than str[i]
        let count = 0;
 
        // Loop through the characters after str[i]
        for (let j = i + 1; j < n; j++) {
            // If str[i] is greater than str[j], increment the count variable
            if (str[i] > str[j]) {
                count++;
            }
        }
 
        // Update the rank based on the count of characters less than str[i]
        // multiplied by the factorial of the number of remaining characters
        rank += count * fact(n - i - 1);
    }
 
    // Return the final rank of the input string
    return rank;
}
 
// Define the main function
function main() {
    // Define a test string
    const str = "string";
    // Call the findRank function on the test string and print the result
    console.log(findRank(str));
}
 
// Call the main function to start the program
main();


Output

598




Time Complexity: O(N2) where N is the size of the string
Auxiliary Space: O(1)

Lexicographic rank of a String using the concept of permutation:

The problem can be solved using the concept of permutation, based on the following idea:

For characters in each index, find how many lexicographically smaller strings can be formed when all the characters till that index are fixed. This will give the strings smaller than that and we can get the rank.

For a better understanding follow the below illustration.

Illustration:

Let the given string be “STRING”. In the input string, ‘S’ is the first character. There are total 6 characters and 4 of them are smaller than ‘S’. So there can be 4 * 5! smaller strings where first character is smaller than ‘S’, like following 

  • G X X X X X
  • R X X X X X
  • I X X X X X
  • N X X X X X

Similarly we can use the same process for the other letters. Fix ‘S’ and find the smaller strings starting with ‘S’. 

  • Repeat the same process for T, rank is 4*5! + 4*4! +. . . 
  • Now fix T and repeat the same process for R, rank is 4*5! + 4*4! + 3*3! + . . .
  • Now fix R and repeat the same process for I, rank is 4*5! + 4*4! + 3*3! + 1*2! + . . . 
  • Now fix I and repeat the same process for N, rank is 4*5! + 4*4! + 3*3! + 1*2! + 1*1! + . . .
  • Now fic N and repeat the same process for G, rank is 4*5! + 4*4! + 3*3! + 1*2! + 1*1! + 0*0!  

If this process is continued the rank = 4*5! + 4*4! + 3*3! + 1*2! + 1*1! + 0*0! = 597. The above computations find count of smaller strings. Therefore rank of given string is count of smaller strings plus 1. The final rank = 1 + 597 = 598

Follow the steps mentioned below to implement the idea:

  • Iterate the string from i = 0 to length of string:
    • Find the number of characters smaller than the current character.
    • Calculate the number of lexicographically smaller that can be formed using them as shown above.
    • Add that value to the rank.
  • At the end, add 1 with rank and return it as the required answer. [the reason is mentioned above]

Below is the implementation of the above approach.  

C++




// C++ program to find lexicographic rank
// of a string
 
#include <bits/stdc++.h>
using namespace std;
 
// A utility function to find
// factorial of n
int fact(int n) {
    return (n <= 1) ? 1 : n * fact(n - 1);
}
 
// A utility function to count
// smaller characters on right of arr[low]
int findSmallerInRight(string str, int low, int high)
{
    int countRight = 0, i;
 
    for (i = low + 1; i <= high; ++i)
        if (str[i] < str[low])
            ++countRight;
 
    return countRight;
}
 
// A function to find rank of a string
// in all permutations of characters
int findRank(string str)
{
    int len = str.size();
    int mul = fact(len);
    int rank = 1;
    int countRight;
 
    int i;
    for (i = 0; i < len; ++i) {
        mul /= len - i;
 
        // Count number of chars smaller than str[i]
        // from str[i+1] to str[len-1]
        countRight = findSmallerInRight(str, i, len - 1);
 
        rank += countRight * mul;
    }
 
    return rank;
}
 
// Driver code
int main()
{
    string str = "string";
 
    // Function call
    cout << findRank(str);
    return 0;
}
 
// This code is contributed by Akanksha Rai


C




// C program to find lexicographic rank
// of a string
 
#include <stdio.h>
#include <string.h>
 
// A utility function to find factorial of n
int fact(int n) {
    return (n <= 1) ? 1 : n * fact(n - 1);
}
 
// A utility function to count smaller characters
// on right of arr[low]
int findSmallerInRight(char* str, int low, int high)
{
    int countRight = 0, i;
 
    for (i = low + 1; i <= high; ++i)
        if (str[i] < str[low])
            ++countRight;
 
    return countRight;
}
 
// A function to find rank of a string
// in all permutations of characters
int findRank(char* str)
{
    int len = strlen(str);
    int mul = fact(len);
    int rank = 1;
    int countRight;
 
    int i;
    for (i = 0; i < len; ++i) {
        mul /= len - i;
 
        // Count number of chars smaller than str[i]
        // from str[i+1] to str[len-1]
        countRight = findSmallerInRight(str, i, len - 1);
 
        rank += countRight * mul;
    }
 
    return rank;
}
 
// Driver code
int main()
{
    char str[] = "string";
   
    // Function call
    printf("%d", findRank(str));
    return 0;
}


Java




// Java program to find lexicographic rank
// of a string
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // A utility function to find factorial of n
    static int fact(int n)
    {
        return (n <= 1) ? 1 : n * fact(n - 1);
    }
 
    // A utility function to count smaller
    // characters on right of arr[low]
    static int findSmallerInRight(String str, int low,
                                  int high)
    {
        int countRight = 0, i;
 
        for (i = low + 1; i <= high; ++i)
            if (str.charAt(i) < str.charAt(low))
                ++countRight;
 
        return countRight;
    }
 
    // A function to find rank of a string in
    // all permutations of characters
    static int findRank(String str)
    {
        int len = str.length();
        int mul = fact(len);
        int rank = 1;
        int countRight;
 
        for (int i = 0; i < len; ++i) {
            mul /= len - i;
 
            // Count number of chars smaller
            // than str[i] from str[i+1] to
            // str[len-1]
            countRight
                = findSmallerInRight(str, i, len - 1);
 
            rank += countRight * mul;
        }
 
        return rank;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String str = "string";
       
        // Function call
        System.out.println(findRank(str));
    }
}
 
// This code is contributed by Nikita Tiwari.


Python3




# Python program to find lexicographic
# rank of a string
 
# A utility function to find factorial
# of n
def fact(n):
    f = 1
    while n >= 1:
        f = f * n
        n = n - 1
    return f
 
# A utility function to count smaller
# characters on right of arr[low]
def findSmallerInRight(st, low, high):
    countRight = 0
    i = low + 1
    while i <= high:
        if st[i] < st[low]:
            countRight = countRight + 1
        i = i + 1
 
    return countRight
 
# A function to find rank of a string
# in all permutations of characters
def findRank(st):
    ln = len(st)
    mul = fact(ln)
    rank = 1
    i = 0
 
    while i < ln:
        mul = mul // (ln - i)
 
        # count number of chars smaller
        # than str[i] from str[i + 1] to
        # str[len-1]
        countRight = findSmallerInRight(st, i, ln-1)
 
        rank = rank + countRight * mul
        i = i + 1
 
    return rank
 
 
# Driver code
if __name__ == '__main__':
    st = "string"
     
    # Function call
    print(findRank(st))
 
# This code is contributed by Nikita Tiwari.


C#




// C# program to find lexicographic rank
// of a string
using System;
 
class GFG {
 
    // A utility function to find factorial of n
    static int fact(int n)
    {
        return (n <= 1) ? 1 : n * fact(n - 1);
    }
 
    // A utility function to count smaller
    // characters on right of arr[low]
    static int findSmallerInRight(string str, int low,
                                  int high)
    {
        int countRight = 0, i;
 
        for (i = low + 1; i <= high; ++i)
            if (str[i] < str[low])
                ++countRight;
 
        return countRight;
    }
 
    // A function to find rank of a string in
    // all permutations of characters
    static int findRank(string str)
    {
        int len = str.Length;
        int mul = fact(len);
        int rank = 1;
        int countRight;
 
        for (int i = 0; i < len; ++i) {
            mul /= len - i;
 
            // Count number of chars smaller
            // than str[i] from str[i+1] to
            // str[len-1]
            countRight
                = findSmallerInRight(str, i, len - 1);
 
            rank += countRight * mul;
        }
 
        return rank;
    }
 
    // Driver code
    public static void Main()
    {
        string str = "string";
       
        // Function call
        Console.Write(findRank(str));
    }
}
 
// This code is contributed nitin mittal.


Javascript




<script>
 
// JavaScript program to find lexicographic rank
 
// A utility function to find factorial of n
function fact(n)
{
    return (n <= 1) ? 1 : n * fact(n - 1);
}
 
// A utility function to count smaller
// characters on right of arr[low]
function findSmallerInRight(str, low, high)
{
    let countRight = 0;
    let i;
     
    for(i = low + 1; i <= high; ++i)
        if (str[i] < str[low])
            ++countRight;
 
    return countRight;
}
 
// A function to find rank of a string
// in all permutations of characters
function findRank(str)
{
    let len = (str).length;
    let mul = fact(len);
    let rank = 1;
    let countRight;
    let i;
     
    for(i = 0; i < len; ++i)
    {
        mul /= len - i;
 
        // count number of chars smaller than str[i]
        // from str[i+1] to str[len-1]
        countRight = findSmallerInRight(str, i, len - 1);
 
        rank += countRight * mul;
    }
    return rank;
}
 
// Driver code
let str = "string";
document.write(findRank(str));
 
// This code is contributed by rohan07
 
</script>


PHP




<?php
// A utility function to find factorial of n
function fact($n)
{
    return ($n <= 1) ? 1 :$n * fact($n - 1);
}
 
// A utility function to count smaller
// characters on right of arr[low]
function findSmallerInRight($str, $low, $high)
{
    $countRight = 0;
 
    for ($i = $low + 1; $i <= $high; ++$i)
        if ($str[$i] < $str[$low])
            ++$countRight;
 
    return $countRight;
}
 
// A function to find rank of a string
// in all permutations of characters
function findRank ($str)
{
    $len = strlen($str);
    $mul = fact($len);
    $rank = 1;
 
    for ($i = 0; $i < $len; ++$i)
    {
        $mul /= $len - $i;
 
        // count number of chars smaller than
        // str[i] from str[i+1] to str[len-1]
        $countRight = findSmallerInRight($str, $i,
                                         $len - 1);
 
        $rank += $countRight * $mul ;
    }
 
    return $rank;
}
 
// Driver Code
$str = "string";
echo findRank($str);
 
// This code is contributed by ChitraNayal
?>


Output

598




Time Complexity: O(N2)
Auxiliary Space: O(1)

Lexicographic rank of a String in linear time:

The idea of the solution is the same as the above approach. The time complexity can be reduced by creating an auxiliary array of size 256.

Create an array to store the number of characters smaller than the ith character in the whole string and update it after each index of the given string during the iteration of the string.

Below is the implementation of the above approach.

C++




// A O(n) solution for finding rank of string
 
#include <bits/stdc++.h>
using namespace std;
#define MAX_CHAR 256
 
// A utility function to find factorial of n
int fact(int n) {
    return (n <= 1) ? 1 : n * fact(n - 1);
}
 
// Construct a count array where value at every index
// contains count of smaller characters in whole string
void populateAndIncreaseCount(int* count, string str)
{
    int i;
 
    for (i = 0; str[i]; ++i)
        ++count[str[i]];
 
    for (i = 1; i < MAX_CHAR; ++i)
        count[i] += count[i - 1];
}
 
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
void updatecount(int* count, char ch)
{
    int i;
    for (i = ch; i < MAX_CHAR; ++i)
        --count[i];
}
 
// A function to find rank of a string in all permutations
// of characters
int findRank(string str)
{
    int len = str.size();
    int mul = fact(len);
    int rank = 1, i;
 
    // All elements of count[] are initialized with 0
    int count[MAX_CHAR] = { 0 };
 
    // Populate the count array such that count[i]
    // contains count of characters which are present
    // in str and are smaller than i
    populateAndIncreaseCount(count, str);
 
    for (i = 0; i < len; ++i) {
        mul /= len - i;
 
        // Count number of chars smaller than str[i]
        // from str[i+1] to str[len-1]
        rank += count[str[i] - 1] * mul;
 
        // Reduce count of characters greater than str[i]
        updatecount(count, str[i]);
    }
 
    return rank;
}
 
// Driver code
int main()
{
    string str = "string";
   
    // Function call
    cout << findRank(str);
    return 0;
}
 
// This is code is contributed by rathbhupendra


C




// A O(n) solution for finding rank of string
 
#include <stdio.h>
#include <string.h>
#define MAX_CHAR 256
 
// A utility function to find factorial of n
int fact(int n) {
    return (n <= 1) ? 1 : n * fact(n - 1);
}
 
// Construct a count array where value at every index
// contains count of smaller characters in whole string
void populateAndIncreaseCount(int* count, char* str)
{
    int i;
 
    for (i = 0; str[i]; ++i)
        ++count[str[i]];
 
    for (i = 1; i < MAX_CHAR; ++i)
        count[i] += count[i - 1];
}
 
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
void updatecount(int* count, char ch)
{
    int i;
    for (i = ch; i < MAX_CHAR; ++i)
        --count[i];
}
 
// A function to find rank of a string in all permutations
// of characters
int findRank(char* str)
{
    int len = strlen(str);
    int mul = fact(len);
    int rank = 1, i;
 
    // All elements of count[] are initialized with 0
    int count[MAX_CHAR] = { 0 };
 
    // Populate the count array such that count[i]
    // contains count of characters which are present
    // in str and are smaller than i
    populateAndIncreaseCount(count, str);
 
    for (i = 0; i < len; ++i) {
        mul /= len - i;
 
        // Count number of chars smaller than str[i]
        // from str[i+1] to str[len-1]
        rank += count[str[i] - 1] * mul;
 
        // Reduce count of characters greater than str[i]
        updatecount(count, str[i]);
    }
 
    return rank;
}
 
// Driver code
int main()
{
    char str[] = "string";
   
    // Function call
    printf("%d", findRank(str));
    return 0;
}


Java




// A O(n) solution for finding rank of string
 
class GFG {
 
    static int MAX_CHAR = 256;
 
    // A utility function to find factorial of n
    static int fact(int n)
    {
        return (n <= 1) ? 1 : n * fact(n - 1);
    }
 
    // Construct a count array where value at every index
    // contains count of smaller characters in whole string
    static void populateAndIncreaseCount(int[] count,
                                         String str)
    {
        int i;
 
        for (i = 0; i < str.length(); ++i)
            ++count[str.charAt(i)];
 
        for (i = 1; i < MAX_CHAR; ++i)
            count[i] += count[i - 1];
    }
 
    // Removes a character ch from count[] array
    // constructed by populateAndIncreaseCount()
    static void updatecount(int[] count, char ch)
    {
        int i;
        for (i = ch; i < MAX_CHAR; ++i)
            --count[i];
    }
 
    // A function to find rank of a string in all
    // permutations of characters
    static int findRank(String str)
    {
        int len = str.length();
        int mul = fact(len);
        int rank = 1, i;
 
        // All elements of count[] are initialized with 0
        int count[] = new int[MAX_CHAR];
 
        // Populate the count array such that count[i]
        // contains count of characters which are present
        // in str and are smaller than i
        populateAndIncreaseCount(count, str);
 
        for (i = 0; i < len; ++i) {
            mul /= len - i;
 
            // count number of chars smaller than str[i]
            // from str[i+1] to str[len-1]
            rank += count[str.charAt(i) - 1] * mul;
 
            // Reduce count of characters greater than
            // str[i]
            updatecount(count, str.charAt(i));
        }
 
        return rank;
    }
 
    // Driver code
    public static void main(String args[])
    {
        String str = "string";
        System.out.println(findRank(str));
    }
}
 
// This code has been contributed by 29AjayKumar


Python3




# A O(n) solution for finding rank of string
MAX_CHAR = 256
 
# All elements of count[] are initialized with 0
count = [0]*(MAX_CHAR + 1)
 
# A utility function to find factorial of n
def fact(n):
    return 1 if(n <= 1) else (n * fact(n - 1))
 
# Construct a count array where value at every index
# contains count of smaller characters in whole string
def populateAndIncreaseCount(str):
    for i in range(len(str)):
        count[ord(str[i])] += 1
 
    for i in range(1, MAX_CHAR):
        count[i] += count[i - 1]
 
# Removes a character ch from count[] array
# constructed by populateAndIncreaseCount()
def updatecount(ch):
 
    for i in range(ord(ch), MAX_CHAR):
        count[i] -= 1
 
# A function to find rank of a string in all permutations
# of characters
def findRank(str):
    len1 = len(str)
    mul = fact(len1)
    rank = 1
 
    # Populate the count array such that count[i]
    # contains count of characters which are present
    # in str and are smaller than i
    populateAndIncreaseCount(str)
 
    for i in range(len1):
        mul = mul//(len1 - i)
 
        # count number of chars smaller than str[i]
        # from str[i+1] to str[len-1]
        rank += count[ord(str[i]) - 1] * mul
 
        # Reduce count of characters greater than str[i]
        updatecount(str[i])
 
    return rank
 
 
# Driver code
if __name__ == '__main__':
    str = "string"
    print(findRank(str))
 
# This is code is contributed by chandan_jnu


C#




// A O(n) solution for finding rank of string
using System;
 
class GFG {
 
    static int MAX_CHAR = 256;
 
    // A utility function to find factorial of n
    static int fact(int n)
    {
        return (n <= 1) ? 1 : n * fact(n - 1);
    }
 
    // Construct a count array where value at every index
    // contains count of smaller characters in whole string
    static void populateAndIncreaseCount(int[] count,
                                         char[] str)
    {
        int i;
 
        for (i = 0; i < str.Length; ++i)
            ++count[str[i]];
 
        for (i = 1; i < MAX_CHAR; ++i)
            count[i] += count[i - 1];
    }
 
    // Removes a character ch from count[] array
    // constructed by populateAndIncreaseCount()
    static void updatecount(int[] count, char ch)
    {
        int i;
        for (i = ch; i < MAX_CHAR; ++i)
            --count[i];
    }
 
    // A function to find rank of a string in all
    // permutations of characters
    static int findRank(char[] str)
    {
        int len = str.Length;
        int mul = fact(len);
        int rank = 1, i;
 
        // all elements of count[] are initialized with 0
        int[] count = new int[MAX_CHAR];
 
        // Populate the count array such that count[i]
        // contains count of characters which are present
        // in str and are smaller than i
        populateAndIncreaseCount(count, str);
 
        for (i = 0; i < len; ++i) {
            mul /= len - i;
 
            // count number of chars smaller than str[i]
            // from str[i+1] to str[len-1]
            rank += count[str[i] - 1] * mul;
 
            // Reduce count of characters greater than
            // str[i]
            updatecount(count, str[i]);
        }
 
        return rank;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        char[] str = "string".ToCharArray();
        Console.WriteLine(findRank(str));
    }
}
 
/* This code contributed by PrinciRaj1992 */


Javascript




<script>
// A O(n) solution for finding rank of string
let MAX_CHAR = 256;
 
 // A utility function to find factorial of n
function fact(n)
{
    return (n <= 1) ? 1 : n * fact(n - 1);
}
 
// Construct a count array where value at every index
    // contains count of smaller characters in whole string
function populateAndIncreaseCount(count,str)
{
    let i;
  
        for (i = 0; i < str.length; ++i)
            ++count[str[i].charCodeAt(0)];
  
        for (i = 1; i < MAX_CHAR; ++i)
            count[i] += count[i - 1];
}
 
// Removes a character ch from count[] array
    // constructed by populateAndIncreaseCount()
function updatecount(count,ch)
{
    let i;
        for (i = ch.charCodeAt(0); i < MAX_CHAR; ++i)
            --count[i];
}
 
// A function to find rank of a string in all permutations
    // of characters
function findRank(str)
{
    let len = str.length;
        let mul = fact(len);
        let rank = 1, i;
  
        // all elements of count[] are initialized with 0
        let count = new Array(MAX_CHAR);
         for(let i = 0; i < count.length; i++)
        {
            count[i] = 0;
        }
         
        // Populate the count array such that count[i]
        // contains count of characters which are present
        // in str and are smaller than i
        populateAndIncreaseCount(count, str);
  
        for (i = 0; i < len; ++i) {
            mul = Math.floor(mul/(len - i));
  
            // count number of chars smaller than str[i]
            // from str[i+1] to str[len-1]
            rank += count[str[i].charCodeAt(0) - 1] * mul;
  
            // Reduce count of characters greater than str[i]
            updatecount(count, str[i]);
        }
  
        return rank;
}
 
// Driver code
let str= "string".split("");
document.write(findRank(str));
 
// This code is contributed by rag2127
</script>


PHP




<?php
// A O(n) solution for finding rank of string
$MAX_CHAR=256;
 
// A utility function to find factorial of n
function fact($n)
{
    return ($n <= 1) ? 1 : $n * fact($n - 1);
}
 
// Construct a count array where value at every index
// contains count of smaller characters in whole string
function populateAndIncreaseCount(&$count, $str)
{
global $MAX_CHAR;
    for ($i = 0; $i < strlen($str); ++$i)
        ++$count[ord($str[$i])];
 
    for ($i = 1; $i < $MAX_CHAR; ++$i)
        $count[$i] += $count[$i - 1];
}
 
// Removes a character ch from count[] array
// constructed by populateAndIncreaseCount()
function updatecount(&$count, $ch)
{
    global $MAX_CHAR;
    for ($i = ord($ch); $i < $MAX_CHAR; ++$i)
        --$count[$i];
}
 
// A function to find rank of a string in all permutations
// of characters
function findRank($str)
{
    global $MAX_CHAR;
    $len = strlen($str);
    $mul = fact($len);
    $rank = 1;
 
    // all elements of count[] are initialized with 0
    $count=array_fill(0, $MAX_CHAR + 1, 0);
 
    // Populate the count array such that count[i]
    // contains count of characters which are present
    // in str and are smaller than i
    populateAndIncreaseCount($count, $str);
 
    for ($i = 0; $i < $len; ++$i)
    {
        $mul = (int)($mul/($len - $i));
 
        // count number of chars smaller than str[i]
        // from str[i+1] to str[len-1]
        $rank += $count[ord($str[$i]) - 1] * $mul;
 
        // Reduce count of characters greater than str[i]
        updatecount($count, $str[$i]);
    }
 
    return $rank;
}
 
    // Driver code
    $str = "string";
    echo findRank($str);
 
// This is code is contributed by chandan_jnu
?>


Output

598




Time Complexity: O(N)
Auxiliary Space: O(1) as we are using an array of size 256

Note: The above programs don’t work for duplicate characters. To make them work for duplicate characters, find all the characters that are smaller (include equal this time also), do the same as above but, this time divide the rank so formed by p! where p is the count of occurrences of the repeating character. 



Last Updated : 16 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads