【问题标题】:Infinite Loop for finding a power set for a string无限循环,用于查找字符串的幂集
【发布时间】:2020-08-01 03:43:27
【问题描述】:

我正在解决一个问题,我需要找到给定字符串的所有幂集,它们是所有可能的子集。我觉得我已经接近我当前的代码,但我不知道为什么我在第二次迭代中陷入无限循环。我通过调试器运行它,但我似乎仍然无法弄清楚,即使我确信它非常简单。当i = 0 进入第二个循环时,j = 0 && j < 1 例如如果help 是我给定的str 参数,那么我希望它添加j + '' 并将其推送到我的allSubsets 数组中。问题是j 迭代将继续循环并执行j++ 并且永远不会停止。我不确定这是为什么。一个特殊的问题,即使我解决了这个无限循环 - 我是否需要在迭代中更新 allSubsets.length 以使其与推送的字符串一起更新?

var powerSet = function(str) {

   let allSubsets = [''];

   for (let i = 0; i < str.length; i++) {
    debugger;
        for (let j = 0; j < allSubsets.length; j++) {
            allSubsets.push(sortLetters(str[i] + allSubsets[j]));
        }
   }
   return allSubsets;
};

var sortLetters = (word => {
    //convert string to an array
    //use the sort to sort by letter
    //convert array back to string and return
    return word.split('').sort().join('');
})

【问题讨论】:

  • 旁注:由于您需要以 (2^length) 元素结束,因此基本嵌套循环极不可能(通常是 length^2,也不清楚您对代码的期望)还不够。
  • 在第二个 for 循环中,您为每次迭代更新 allSubsets 数组,因此循环永远不会停止,并且相同的元素将无限次推送到 allSubsets 数组。检查您可以更改可以迭代第二个循环的位置
  • @AlexeiLevenkov 对不起,我是新手,但你怎么知道它的 2^length 元素?我期待的是这个。例如,如果字符串参数是jump,那么allSubsets =[ '', 'j', 'u', 'ju', 'm', 'jm', 'mu', 'jmu', 'p', 'jp', 'pu', 'jpu', 'mp', 'jmp', 'mpu', 'jmpu' ]
  • 每个元素要么包括给定的字母 (1) 要么跳过 (0),所以你得到 - 0000 (""), 0001 ("p"), 0010 ("m"), 0011 (" mp"),... 1111 ("jump") - 正好是 2^4。您正在尝试以不同的顺序生成它们,这很好,但是由于重新排序,集合中的元素总数不会改变。
  • @upender 谢谢!我不知道我是怎么完全错过的——这将是一个无限循环是有道理的。我固定了在第一个循环的每次迭代开始时要计算的长度,它可以工作

标签: javascript string subset


【解决方案1】:

每次你推送到allSubSets,长度都会增加,因此你的循环永远不会结束。声明性循环在初始循环的范围内运行。请参阅下面的基于您的代码的修复:

var powerSet = function(str) {

   let allSubsets = [''];

   for (let i = 0; i < str.length; i++) {
        allSubsets.forEach( (_char, j) => { // declarative loop here
            allSubsets.push(sortLetters(str[i] + allSubsets[j]));
        })
   }
   return allSubsets;
};

var sortLetters = (word => {
    return word.split('').sort().join('');
})

来自 MDN 网络文档:

forEach() 处理的元素范围是在第一次调用回调之前设置的。在对 forEach() 的调用开始后附加到数组的元素将不会被回调访问。如果数组的现有元素被更改或删除,它们传递给回调的值将是 forEach() 访问它们时的值;在被访问之前被删除的元素不会被访问。如果在迭代期间删除了已经访问过的元素(例如使用 shift()),则将跳过后面的元素。 (请参见下面的示例。)

见描述下的第四段:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多