用于生成长度为 n 的 Lyndon 单词的 C++ 程序

data structurec++server side programming

在此问题中,我们需要使用给定的字符生成长度为 n 的 Lyndon 单词。Lyndon 单词是这样的单词:其任何旋转都严格大于其本身的字典顺序。

以下是 Lyndon 单词的示例。

  • 01 − '01' 的旋转为 '10',始终严格大于 '01'。

  • 012 − '012' 的旋转为 '120' 和 '210',严格大于 '012'。

问题陈述 − 我们给出了一个包含数字字符的数组 s[]。另外,我们给出了 n 来表示 Lyndon 单词的长度。我们需要使用数组字符生成长度为 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);
    // 用于存储索引
    vector<int> chars;
    // 初始索引为 -1
    chars.push_back(-1);
    // 进行迭代,直到 chars 的大小大于 0
    while (chars.size() > 0) {
        // 将最后一个字符增加 1
        chars[chars.size() - 1]++;
        // 存储数组的大小
        int chars_size = chars.size();
        // 如果大小等于 len,则我们找到了 Lyndon 单词
        if (chars_size == len) {
            // 打印单词
            string temp;
            for (int p = 0; p < chars.size(); p++) {
                temp += characters[chars[p]];
            }
            cout << temp << endl;
        }
        // 继续添加字符,直到其长度等于 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 << "长度为 2 的 Lyndon 单词为 :- \n ";
    generateLydonWord(S, array_len, n);
    return 0;
}

输出

长度为 2 的 Lyndon 单词为:-
01
02
12

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

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

我们学会了使用 Duval 算法来查找给定长度的 Lyndon 单词。此外,我们还调试了示例输入以了解 Duval 算法的工作原理。


相关文章