给定一个字符串,在按字典顺序排列的所有排列中找到它的排名。例如,“abc”的排名是1,“acb”的排名是2,“cba”的排名是6。
例如:
Input : str[] = "acb"Output : Rank = 2Input : str[] = "string"Output : Rank = 598Input : str[] = "cba"Output : Rank = 6
为了简单起见,我们假设字符串不包含任何重复字符。
一个简单的解决方案是将秩初始化为1, 按字典顺序生成所有排列 .生成置换后,检查生成的置换是否与给定字符串相同,如果相同,则返回秩,如果不相同,则将秩增加1。在最坏的情况下,该解决方案的时间复杂度将是指数级的。下面是一个有效的解决方案。
让给定的字符串为“string”。在输入字符串中,“S”是第一个字符。共有6个字符,其中4个小于“S”。所以可以有4*5!第一个字符小于“S”的较小字符串,如下所示 R X X X X I X X X X N X X X X G X X X X 现在让我们修复’S’并找到以’S’开头的较小字符串。
对T重复同样的过程,秩为4*5!+4*4! +…
现在修正T,对R重复同样的过程,秩是4*5!+4*4! + 3*3! +…
现在修正R,对I重复同样的过程,秩是4*5!+4*4! + 3*3! + 1*2! +…
现在修正I,对N重复同样的过程,秩是4*5!+4*4! + 3*3! + 1*2! + 1*1! +…
现在修正N,对G重复同样的过程,秩是4*5!+4*4! + 3*3! + 1*2! + 1*1! + 0*0!
排名=4*5!+4*4! + 3*3! + 1*2! + 1*1! + 0*0! = 597
请注意,上面的计算找到了较小字符串的计数。因此,给定字符串的秩是较小字符串的计数加1。最终排名=1+597=598
以下是上述方法的实施情况:
C++
// C++ program to find lexicographic rank // of a string #include <bits/stdc++.h> #include <string.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( 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 program to test above function int main() { char str[] = "string" ; 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 program to test above function int main() { char str[] = "string" ; 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 program to test above function public static void main(String[] args) { String str = "string" ; 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 program to test above function st = "string" 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 program to test above function public static void Main() { string str = "string" ; Console.Write(findRank(str)); } } // This code is contributed nitin mittal. |
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 ?> |
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> |
输出:
598
上述解的时间复杂度为O(n^2)。通过创建一个大小为256的辅助数组,我们可以将时间复杂度降低到O(n)。请参阅下面的代码。
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, 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 program to test above function int main() { char str[] = "string" ; 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 program to test above function int main() { char str[] = "string" ; 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, 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(); 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 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 */ |
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 ?> |
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> |
输出:
598
上述程序不适用于重复字符。为了使它们适用于重复的字符,找到所有较小的字符(这次也包括相等的字符),执行与上面相同的操作,但这次将由p构成的秩除以!其中p是重复字符的出现次数。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。