Generating Lyndon words of length n
Last Updated : 09 Sep, 2022
Given an integer n and an array of characters S, the task is to generate Lyndon words of length n having characters from S.
A Lyndon word is a string which is strictly less than all of its rotations in lexicographic order. For example, the string "012" is a Lyndon word as it is less than its rotations "120" and "201", but "102" is not a Lyndon word as it is greater than its rotation "021".
Note: "000" is not considered to be a Lyndon word as it is equal to the string obtained by rotating it.
Examples:
Input: n = 2, S = {0, 1, 2}
Output: 01 02 12
Other possible strings of length 2 are "00", "11", "20", "21", and "22". All of these are either greater than or equal to one of their rotations.
Input: n = 1, S = {0, 1, 2}
Output: 0 1 2
Approach:
There exists an efficient approach to generate Lyndon words which was given by Jean-Pierre Duval, which can be used to generate all the Lyndon words upto length n in time proportional to the number of such words. (Please refer to the paper "Average cost of Duval’s algorithm for generating Lyndon words" by Berstel et al. for the proof) The algorithm generates the Lyndon words in lexicographic order.
If w is a Lyndon word, the next word is obtained by the following steps:
- Repeat w to form a string v of length n, such that v[i] = w[i mod |w|].
- While the last character of v is the last one in the sorted ordering of S, remove it.
- Replace the last character of v by its successor in the sorted ordering of S.
For example, if n = 5, S = {a, b, c, d}, and w = "add" then we get v = "addad". Since 'd' is the last character in the sorted ordering of S, we remove it to get "adda" and then replace the last 'a' by its successor 'b' to get the Lyndon word "addb".
Below is the implementation of the above approach:
C++ // C++ implementation of // the above approach #include<bits/stdc++.h> using namespace std; int main() { int n = 2; char S[] = {'0', '1', '2' }; int k = 3; sort(S, S + 3); // To store the indices // of the characters vector<int> w; w.push_back(-1); // Loop till w is not empty while(w.size() > 0) { // Incrementing the last character w[w.size()-1]++; int m = w.size(); if(m == n) { string str; for(int i = 0; i < w.size(); i++) { str += S[w[i]]; } cout << str << endl; } // Repeating w to get a // n-length string while(w.size() < n) { w.push_back(w[w.size() - m]); } // Removing the last character // as long it is equal to // the largest character in S while(w.size() > 0 && w[w.size() - 1] == k - 1) { w.pop_back(); } } return 0; } // This code is contributed by AdeshSingh1
Java // Java program to check if a string is two time // rotation of another string. import java.util.*; public class Main { // Driver method public static void main(String[] args) { int n=2; char S[]={'0', '1', '2' }; int k = 3; Arrays.sort(S); // To store the indices // of the characters ArrayList<Integer> w = new ArrayList<Integer>(); w.add(-1); // Loop till w is not empty while(w.size() > 0) { // Incrementing the last character Integer value = w.get(w.size()-1); // get value value = value + 1; // increment value w.set(w.size()-1, value); // replace value int m = w.size(); if(m == n) { String str=""; for(int i = 0; i < w.size(); i++) { value = w.get(i); str += S[value]; } System.out.println(str); } // Repeating w to get a // n-length string while(w.size() < n) { value = w.size() - m; value = w.get(value); w.add(value); } // Removing the last character // as long it is equal to // the largest character in S while(w.size() > 0 && w.get(w.size() - 1) == k - 1) { w.remove(w.size()-1); } } } } // This code is contributed by Aarti_Rathi
Python3 # Python implementation of # the above approach n = 2 S = ['0', '1', '2'] k = len(S) S.sort() # To store the indices # of the characters w = [-1] # Loop till w is not empty while w: # Incrementing the last character w[-1] += 1 m = len(w) if m == n: print(''.join(S[i] for i in w)) # Repeating w to get a # n-length string while len(w) < n: w.append(w[-m]) # Removing the last character # as long it is equal to # the largest character in S while w and w[-1] == k - 1: w.pop()
C# using System; using System.Collections.Generic; class GFG { // Driver code public static void Main () { int n=2; char [] S={'0', '1', '2' }; int k = 3; Array.Sort(S); // To store the indices // of the characters List<int> w = new List<int>(); w.Add(-1); // Loop till w is not empty while(w.Count > 0) { // Incrementing the last character w[w.Count-1]++; int m = w.Count; if(m == n) { string str=""; for(int i = 0; i < w.Count; i++) { str += S[w[i]]; } Console.WriteLine(str); } // Repeating w to get a // n-length string while(w.Count < n) { w.Add(w[w.Count - m]); } // Removing the last character // as long it is equal to // the largest character in S while(w.Count > 0 && w[w.Count - 1] == k - 1) { w.RemoveAt(w.Count-1); } } } } // This code is contributed by Aarti_Rathi
JavaScript <script> // JavaScript implementation of // the above approach // driver code let n = 2; let S = ['0', '1', '2']; let k = 3; S.sort(); // To store the indices // of the characters let w = []; w.push(-1); // Loop till w is not empty while(w.length > 0) { // Incrementing the last character w[w.length-1]++; let m = w.length; if(m == n) { let str = ""; for(let i = 0; i < w.length; i++) { str += S[w[i]]; } document.write(str,"</br>"); } // Repeating w to get a // n-length string while(w.length < n) { w.push(w[w.length - m]); } // Removing the last character // as long it is equal to // the largest character in S while(w.length > 0 && w[w.length - 1] == k - 1) { w.pop(); } } // This code is contributed by shinjanpatra </script>
Similar Reads
Program for length of the longest word in a sentence Given a string, we have to find the longest word in the input string and then calculate the number of characters in this word.Examples: Input : A computer science portal for geeksOutput : Longest word's length = 8 Input : I am an intern at geeksforgeeksOutput : Longest word's length = 13The idea is
6 min read
Generate the String of length N according to given conditions Given two integers N and M. Then your task is to output the string let's say S of length N by following given conditions: S must be formed by only the first M smaller case letters of the alphabetical series.The length of LPS (Longest palindromic Substring) in S should be the minimum possible.Example
10 min read
CSES Solutions - Word Combinations You are given a string S of length N and a dictionary arr[] containing K words. In how many ways can you create the string using the words? Examples: Input: S = "ababc", K = 4, arr[] = {ab, abab, c, cb}Output: 2Explanation: The possible ways are "ab" + "ab" + "c" and "abab" + "c". Input: S = "geeksf
10 min read
K length words that can be formed from given characters without repetition Given an integer k and a string str consisting of lowercase English alphabets, the task is to count how many k-character words (with or without meaning) can be formed from the characters of str when repetition is not allowed. Examples: Input: str = "cat", k = 3 Output: 6 Required words are "cat", "c
6 min read
Count words in a given string Given a string, count the number of words in it. The words are separated by the following characters: space (' ') or new line ('\n') or tab ('\t') or a combination of these. Recommended PracticeCount number of wordsTry It!Method 1: The idea is to maintain two states: IN and OUT. The state OUT indica
15+ min read