javascript - 如何在 JavaScript 中实现一组字母(小写和大写)的排列生成器(或内存函数)?

标签 javascript algorithm performance

我正在实现一个变量名称生成器,我无法控制所需的变量名称的数量,并且我认为使用生成器或内存函数是可行的方法,而不是创建所有排列的列表并保存内存中。

基本上,我想创建一个函数,以增量方式生成[a-z][A-Z]的所有排列。它应该返回类似以下的序列 {'a', 'b', ...,'z','aa','ab',....,'az', 'ba', 。 ...'aA',...'aTr'...'ZZZ',...'Z(*52)'}

现在我已经,

function* varNameGenerator() {
  const all =
    'abcdefghijklmnopqrstuvwxyz' + 'abcdefghijklmnopqrstuvwxyz'.toUpperCase();
  let prefix = '';
  for (let i = 0; i < all.length; i++) {
    for (let j = 0; j < all.length; j++) {
      yield prefix + all[j];
    }
    prefix += all[i];
  }
}

这有助于生成大约 2705 个结果,因为输出将是集合 {'a', 'b', ...,'aa',.. 中的序列。 .'aZ', 'aba', 'abb'...,'abZ','abca','abcb','abcc',...,'abcZ','abcda'...}等等。这是可用的,但是变量名的长度增加得非常快(每 52 个函数调用)。

那么是否有一种实现可以逐步生成字母表的所有排列,并且首先是长度最小的字母表?

最佳答案

您可以使用递归生成器:

     const ALPHABET = 'abcdefghijklmnopqrstuvwxyz' + 'abcdefghijklmnopqrstuvwxyz'.toUpperCase();

    function* nameGenerator(length = 30, prev = "") {
      if(length <= 0) {
        yield prev;
        return;
      }

      for (const char of ["", ...ALPHABET]) {
        yield* nameGenerator(length - 1, prev + char);
      }
    }
   
    const it = nameGenerator();

    for(let i = 0; i < 100; i++)
      console.log(it.next().value);

它是如何工作的:

  1. 进行了 30 次递归调用,每次调用都向 prev 添加一个字符(第一次迭代中的“”):

    ""-> ""+ ""-> ... -> ""+ ... + ""

  2. 最上面的迭代器返回该值

                 <-- ""
    

然后最上面的循环转到下一个字符“a”,并返回该字符,所有字符都会发生这种情况:

                      -> "" + ... + "a"
                     <-- "a"
                     ...
                     -> "" + ... + "Z"
                     <--- "Z"
  • 循环完成,我们上升一级并继续循环,然后返回循环:

                     <-
        "" + ... + "a" -> "" + ... + "a" + "a"
                     <-- "aa" 
                     <-- "ab"
                     ....
                     <-- "aZ"
    
  • 这种情况一直持续到我们在最下层循环 30 次

    关于javascript - 如何在 JavaScript 中实现一组字母(小写和大写)的排列生成器(或内存函数)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59100184/

    相关文章:

    javascript - 将 onclicklistener 重新附加到按钮

    sql - 在 PostgreSQL 中有效地合并最近日期的两个数据集

    algorithm - KMP 计数字符串出现次数

    algorithm - Haskell 上枚举总和和乘积类型的通用算法?

    c++ - unordered_map查找数组的索引

    javascript - jQuery 检测是否在 ipad/iphone(移动 safari)上并使用 jQuery 触摸对话框而不是常规的 jquery ui 对话框

    asp.net - Sys.Application.add_load 模态弹出窗口扩展程序的问题

    javascript - 使用 jQuery 刷新 div 内容

    c - 使用 Streaming Simd Extensions (SSE) 的按位运算

    reactjs - 在 React 组件中使用展开语法时顺序重要吗?