Find n-th lexicographically permutation of a strings in C++


Concept

With respect of a given string of length m containing lowercase alphabets only, our task to determine the n-th permutation of string lexicographically.

Input

str[] = "pqr", n = 3

Output

Result = "qpr"

Explanation

All possible permutation in sorted order − pqr, prq, qpr, qrp,rpq, rqp

Input

str[] = "xyx", n = 2

Output

Result = "xyx"

Explanation

All possible permutation in sorted order − xxy, xyx, yxx

Method

Here we use some Mathematical concept for solving this problem.

The concept is based on following facts.

  • Here, the total number of permutation of a string generated by N characters (all distinct) is N!

  • Now, the total number of permutation of a string generated by N characters (in this case the frequency of character C1 is M1, C2 is M2… and so the frequency of character Ck is Mk) is N!/(M1! * M2! *….Mk!).

  • Again, the total number of permutation of a string generated by N characters (all distinct) after fixing the

The below steps can be followed to reach the solution.

  • At first, we count frequencies of all characters in an array freq[].

  • At present from the first smallest character present in the string (smallest index i such that

  • freq[i] > 0), we calculate the number of maximum permutation possible after treating that particular i-th character as the first character.

  • It has been seen that if this sum value is higher than given n, after that we set that character as the first result output character, decrement freq[i], and continue same for rest n-1 characters.

  • It has been seen that, on the other hand, if the count is smaller than the required n,iterate for the next character in the frequency table and modify the count over and over again until we determine a character that produces a count higher than the required n.

It should be noted that time complexity of above-mentioned method be O(n) i.e. order of string length.

Example

 Live Demo

// C++ program to print
// n-th permutation
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
const int MAX_CHAR1 = 26;
const int MAX_FACT1 = 20;
ll fact1[MAX_FACT1];
// Shows utility for calculating factorials
void precomputeFactorials(){
   fact1[0] = 1;
   for (int i = 1; i < MAX_FACT1; i++)
      fact1[i] = fact1[i - 1] * i;
}
// Shows function for nth permutation
void nPermute(char str1[], int n1){
   precomputeFactorials();
   // Indicates length of given string
   int len1 = strlen(str1);
   // Used to count frequencies of all
   // characters
   int freq1[MAX_CHAR1] = { 0 };
   for (int i = 0; i < len1; i++)
      freq1[str1[i] - 'a']++;
      // Shows out1 string for output string
      char out1[MAX_CHAR1];
      //Used to iterate till sum equals n1
      int sum1 = 0;
      int k1 = 0;
      // We umodify both n1 and sum1 in this
      // loop.
      while (sum1 != n1) {
         sum1 = 0;
         // Verify for characters present in freq1[]
         for (int i = 0; i < MAX_CHAR1; i++) {
            if (freq1[i] == 0)
               continue;
            // Remove character
            freq1[i]--;
            // Compute sum1 after fixing
            // a particuar char
            int xsum1 = fact1[len1 - 1 - k1];
            for (int j = 0; j < MAX_CHAR1; j++)
               xsum1 /= fact1[freq1[j]];
               sum1 += xsum1;
            // Now if sum1 > n1 fix that char as
            // present char and modify sum1
            // and required nth after fixing
            // char at that position
            if (sum1 >= n1) {
               out1[k1++] = i + 'a';
               n1 -= (sum1 - xsum1);
               break;
            }
            // Now if sum1 < n1, add character back
            if (sum1 < n1)
               freq1[i]++;
         }
      }
      // Now if sum1 == n1 means this
      // char will provide its
      // greatest permutation
      // as nth permutation
      for (int i = MAX_CHAR1 - 1;
         k1 < len1 && i >= 0; i--)
      if (freq1[i]) {
         out1[k1++] = i + 'a';
      freq1[i++]--;
   }
   // Used to append string termination
   // character and print result
   out1[k1] = '\0';
   cout << out1;
}
// Driver program
int main(){
   int n1 = 5;
   char str1[] = "tutorialspoint";
   // int n1 = 3;
   // char str1[] = "pqr";
   //int n1 = 2;
   //char str1[] = "xyx";
   nPermute(str1, n1);
   return 0;
}

Output

aiilnooprtsttu

Updated on: 25-Jul-2020

144 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements