C++ Program for Generating Lyndon Words of Length n


In this problem, we need to generate the Lyndon words of the length n using the given characters. The Lyndon words are words such that any of its rotations is strictly larger than itself in the lexicographical order.

Here are examples of Lyndon words.

  • 01 − The rotations of ‘01’ is ‘10’, which is always strictly greater than ‘01’.

  • 012 − The rotations of ‘012’ is ‘120’ and ‘210’, which is strictly greater than ‘012’.

Problem statement − We have given an array s[] containing numeric characters. Also, we have given n representing the length of Lyndon word. We need to generate the Lyndon words of length n using the array characters.

Sample examples

Input

S[] = {'0', '1', '2'}, n = 2

Output

01, 02, 12

Explanation − We generated the Lyndon words of length 2 using the ‘0’, ‘1’, and ‘2’ characters.

Sample examples

Input

S[] = {'0', '1'}, n = 3

Output

001, 011

Explanation − All rotations of ‘001’ and ‘011’ is lexicographically larger than itself.

Approach 1

We can use Duval’s algorithm to generate Lyndon words. Programmers can follow the below algorithm to generate Lyndon words of length n using the characters of the array.

Algorithm

Step 1 − Use the sort() method to sort the array of characters.

Step 2 − Define the ‘chars’ vector to store the indexes of the characters of the array.

Step 3 − Initially push the ‘−1’ to the ‘chars’ list, representing the starting index.

Step 4 − Use the while loop to make iterations until the size of the ‘chars’ list is greater than zero.

Step 5 − Increment the last index by 1.

Step 6 − Store the list size on the ‘chars_size’ variable.

Step 7 − If ‘chars_size’ is equal to the ‘len’, we found the Lyndon word of length equal to ‘len’. Print all characters of the ‘chars’ list.

Step 8 − Use the loop to append the characters to the ‘chars’ list until the length of the list is less than ‘len’. We can take characters from the ‘chars’ list and keep appending them at the end of the list itself.

Step 9 − If the size of the ‘chars’ list is greater than zero and the last character of the list is equal to the last character of the array, remove it from the list.

Example

Let’s debug the sample input for the example below to understand better.

  • Initially, the chars list will be [−1].

  • The ‘chars’ list will become [0] in the first iteration. After that, size of the list is not equal to ‘len’, so we move ahead. Here, we make a list size of ‘len’, and the updated list will be [0, 0].

  • In the next iteration, we increase the last element by 1 so that the resultant list will be [0, 1]. In this iteration, we have a list size equal to ‘len’, and we can take characters from the 0th and 1st index to create the first Lydon word of length 2, ' 01’.

  • In the next iteration, we increase the last index of the list, and it becomes [0, 2]. Again we find a new Lydon word which is ‘02’. Also, in the ‘chars’ list, the last index element is equal to the ‘array_len − 1’, so remove it, and the updated list is [0].

  • In the next iteration, the last index and updated list will be [1]. Make the list size equal to 2, and the updated list will be [1, 1].

  • In the next iteration, increase the last element by 1; the updated list will be [1, 2]. Here we find the third Lydon word, which is ‘12’.

#include <bits/stdc++.h>
using namespace std;
void generateLydonWord(char characters[], int array_len, int len) {
    sort(characters, characters + array_len);
    // for storing the indexes
    vector<int> chars;
    // Initial index is -1
    chars.push_back(-1);
    // Make iterations till the size of chars is greater than 0
    while (chars.size() > 0) {
        // Increase last char by 1
        chars[chars.size() - 1]++;
        // store the size of the array
        int chars_size = chars.size();
        // If the size is equal to len, we found the Lyndon word
        if (chars_size == len) {
            // Print the word
            string temp;
            for (int p = 0; p < chars.size(); p++) {
                temp += characters[chars[p]];
            }
            cout << temp << endl;
        }
        // keep appending the chars characters until its length becomes equal to len
        while (chars.size() < len) {
            chars.push_back(chars[chars.size() - chars_size]);
        }
        while (chars.size() > 0 && chars[chars.size() - 1] == array_len - 1) {
            chars.pop_back();
        }
    }
}
int main() {
    int n = 2;
    char S[] = {'0', '1', '2'};
    int array_len = sizeof(S) / sizeof(S[0]);
    cout << "The Lyndon words of length 2 are :- \n ";
    generateLydonWord(S, array_len, n);
    return 0;
}

Output

The Lyndon words of length 2 are :- 
 01
02
12

Time complexity− O(N* logN) as we need to sort the array.

Space complexity − O(N) as we use the ‘chars’ array to store the indexes of the element.

We learned to use Duval’s algorithm to find the Lyndon words of the given length. Also, we have debugged the sample input to know how Duval’s algorithm works.

Updated on: 14-Aug-2023

47 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements