C++ 生成长度为 n 的 Lyndon 单词

C++ 生成长度为 n 的 Lyndon 单词

在这个问题中,我们需要使用给定的字符生成长度为 n 的 Lyndon 单词。Lyndon 单词是这样的单词,它的任意一个旋转在字典序中都严格大于它自己。

以下是 Lyndon 单词的示例。

  • 01 − ‘01’ 的旋转是 ‘10’,它始终严格大于‘01’。

  • 012 − ‘012’ 的旋转是 ‘120’ 和 ‘210’,它们严格大于 ‘012’。

问题陈述 − 我们已经给出了一个包含数字字符的数组 s[]。同时,我们给出了表示 Lyndon 单词长度的 n。我们需要使用数组字符生成长度为 n 的 Lyndon 单词。

示例

输入

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

输出

01, 02, 12

解释 - 我们使用字符’0’、’1’和’2’生成了长度为2的Lyndon词。

示例

输入

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

输出

001, 011

解释 - ‘001’ 和 ‘011’ 的所有旋转都按字典顺序大于其本身。

方法1

我们可以使用Duval算法生成Lyndon单词。程序员可以按照以下算法使用数组的字符生成长度为n的Lyndon单词。

步骤

步骤 1 - 使用sort()方法对字符数组进行排序。

步骤 2 - 定义一个‘chars’向量来存储字符数组的索引。

步骤 3 - 最初将‘-1’推入‘chars’列表,表示起始索引。

步骤 4 - 使用while循环进行迭代,直到‘chars’列表的大小大于零。

步骤 5 - 将最后一个索引增加1。

步骤 6 - 将列表大小存储在‘chars_size’变量中。

步骤 7 - 如果‘chars_size’等于‘len’,则找到长度等于‘len’的Lyndon单词。打印‘chars’列表的所有字符。

步骤 8 - 使用循环将字符添加到‘chars’列表,直到列表的长度小于‘len’。我们可以从‘chars’列表获取字符,并将它们追加到列表的末尾。

步骤 9 - 如果‘chars’列表的大小大于零且列表的最后一个字符等于数组的最后一个字符,则从列表中删除它。

示例

我们来调试下面示例的示例输入以更好地理解。

  • 最初,chars列表将为[−1]。

  • 第一次迭代中,chars列表将变为[0]。之后,列表的大小与len不相等,所以我们继续前进。在这里,我们创建一个大小为len的列表,更新后的列表将为[0, 0]。

  • 在下一次迭代中,我们将最后一个元素增加1,使得结果列表为[0, 1]。在这次迭代中,我们的列表大小等于len,并且我们可以从第0个和第1个索引中取字符来创建长度为2的第一个Lydon单词,即’01’。

  • 在下一次迭代中,我们增加列表的最后一个索引,它变为[0, 2]。我们再次找到一个新的Lydon单词,即’02’。还有,在chars列表中,最后一个索引元素等于array_len − 1,因此将其删除,更新后的列表为[0]。

  • 在下一次迭代中,最后一个索引和更新后的列表将为[1]。使列表大小等于2,更新后的列表将为[1, 1]。

  • 在下一次迭代中,将最后一个元素增加1,更新后的列表将为[1, 2]。在这里,我们找到了第三个Lydon单词,即’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;
}

输出

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

时间复杂度: − O(N* logN),因为我们需要对数组进行排序。

空间复杂度: − O(N),因为我们使用’chars’数组来存储元素的索引。

我们学习了如何使用Duval算法找到给定长度的Lyndon词。此外,我们还调试了样例输入以了解Duval算法的工作原理。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程