📜  用于生成长度为 n 的林登词的 C++ 程序

📅  最后修改于: 2022-05-13 01:55:39.787000             🧑  作者: Mango

用于生成长度为 n 的林登词的 C++ 程序

给定一个整数n和一个字符数组S ,任务是生成长度为n的 Lyndon 单词,其中包含来自S的字符。

例子:

方法: Jean-Pierre Duval 给出了一种生成 Lyndon 词的有效方法,该方法可用于生成长度为 n 的所有 Lyndon 词,时间与此类词的数量成正比。 (证明请参考 Berstel 等人的论文《Average cost of Duval's algorithm for generate Lyndon words》)
该算法按字典顺序生成 Lyndon 单词。如果w是一个 Lyndon 词,则通过以下步骤获得下一个词:

  1. 重复w以形成长度为n的字符串v ,使得v[i] = w[i mod |w|]
  2. 虽然v的最后一个字符是S排序顺序中的最后一个字符,但将其删除。
  3. 在 S 的排序顺序中,将v的最后一个字符替换为其后继字符。

下面是上述方法的实现:

C++
// C++ implementation of 
// the above approach 
#include
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 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


输出:
01
02
12

有关详细信息,请参阅有关生成长度为 n 的 Lyndon 词的完整文章!