使用递归生成给定长度和基数的数字字符串

时间:2018-11-18 13:22:50

标签: javascript recursion

我一直在尝试调整以下脚本,以生成给定大小和基数的所有数字字符串。似乎函数返回了错误的str值...有帮助吗?
(下面的脚本应该打印从00001111开始的所有长度为4的二进制字符串)
(我在调用函数之前使用str.replace替换了str的最后一位)

function generateStringsOfLength(size, base, str) {
  if (str.length >= size) {
    document.write(str + "<br>");
    return;
  }
  //outer loop to change position value
  for (let pos = 0; pos < size; pos++) {
    //appending an empty char to the "str", this empty char will be replaced by "val" in each iteration of the below inner loop
    str += " ";
    //inner loop change only the lsb digit from "0" to "base-1" 
    for (let val = 0; val < base; val++) {
      str = str.replace(/.$/, val);
      generateStringsOfLength(size, base, str);
    }
  }
}
generateStringsOfLength(4, 2,"");

编辑:
实际上,我正在尝试归纳和实现以下针对二进制字符串的伪代码:

generateBinary(length, string)    
if(length > 0)
    generateBinary(length-1, string + "0")
    generateBinary(length-1, string + "1")
else
    print(string)

我在代码中所做的唯一修改是使用循环以“基本”时间递归调用该函数...

1 个答案:

答案 0 :(得分:2)

主要问题是您的外部循环使str更长。但是它不应该存在:在递归调用中,该字符串已经已经变长了。该外部循环应删除。

第二,用正则表达式更改数字的方式不是很有效。取而代之的是,仅使用参数传递与附加数字连接的字符串,而无需更改当前上下文中的str的值:

最后,不要使用document.write:这确实是一种不好的做法。而是使用console.log,或者甚至更好,不要在函数本身中输出任何内容。最好让函数以字符串数组形式返回结果,并让调用者决定如何处理它:

function generateStringsOfLength(size, base, str) {
    if (str.length >= size) {
        return [str]; // Don't output. Instead build an array with strings
    }
    const result = [];
    for (let val = 0; val < base; val++) {
        // Don't change str. Instead pass the modified value on-the-fly
        // Collect the result in a growing array
        result.push(...generateStringsOfLength(size, base, str + val));
    }
    return result; // Return the collected strings
}

const result = generateStringsOfLength(4, 2,"");
console.log(result);

我想您正在玩递归,因为这样生成结果要容易得多:

function generateStringsOfLength(size, base, str) {
    return Array.from({length: base ** size}, 
                      (_, i) => i.toString(base).padStart(size, '0'));
}

const result = generateStringsOfLength(4, 2,"");
console.log(result);