【问题标题】:Why are the number of iterations wrong with this yield generator in javascript?为什么javascript中这个yield生成器的迭代次数有误?
【发布时间】:2019-04-03 16:10:32
【问题描述】:

所以这是我正在尝试使用的代码 sn-p。

function* genBubble(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - i - 1; j++) {
      yield arr; // returning arr after every iteration
      if (arr[j] > arr[j + 1]) {
        swap(arr, j, j + 1); // removed swap for brevity
      }
    }
  }
}
const tempArray = [3, 5, 8, 4, 1, 9, -2];
const genForLoop = genBubble(tempArray);

do {
  console.log(genForLoop.next());
} while (!genForLoop.next().done);

这是一个简单的冒泡排序实现。如您所知,冒泡排序有n * (n - 1) / 2 迭代,所以在这种情况下,数组的长度为7,我们有7 * (7 - 1) / 2 迭代等于21

但是当我运行这段代码时,我只会得到11 迭代。输出如下图。

{ value: [ 3, 5, 8, 4, 1, 9, -2 ], done: false }
{ value: [ 3, 5, 8, 4, 1, 9, -2 ], done: false }
{ value: [ 3, 5, 4, 1, 8, 9, -2 ], done: false }
{ value: [ 3, 5, 4, 1, 8, -2, 9 ], done: false }
{ value: [ 3, 4, 5, 1, 8, -2, 9 ], done: false }
{ value: [ 3, 4, 1, 5, 8, -2, 9 ], done: false }
{ value: [ 3, 4, 1, 5, -2, 8, 9 ], done: false }
{ value: [ 3, 1, 4, 5, -2, 8, 9 ], done: false }
{ value: [ 1, 3, 4, -2, 5, 8, 9 ], done: false }
{ value: [ 1, 3, -2, 4, 5, 8, 9 ], done: false }
{ value: [ 1, -2, 3, 4, 5, 8, 9 ], done: false }

我正在使用node test.js 运行这个程序(test.js 是写入这个程序的文件)。

注意:我不想在每次迭代后打印数组。我想退货。如果有帮助的话。

【问题讨论】:

  • 您的do ... while 循环在每次迭代中调用.next() 函数两次
  • 哇,确实如此。如何只调用一次,同时检查是否已完成?
  • x = genForLoop.next(); 在循环内?
  • 将返回值存储在一个变量中,然后在while条件下检查这个变量。事实上,.next()是一个调用,而不是一个值。
  • 如何只调用一次,同时检查是否完成? 删除 do..while 正文或只使用空的 while 循环

标签: javascript iteration generator bubble-sort yield-keyword


【解决方案1】:

您的主要问题是您调用了两次next,但忽略了其他所有呼叫中的value。相反,调用它一次并记住结果:

let result;
while (!(result = genForLoop.next()).done) {
  console.log(result.value.join(","));
}

...或者更简单地说,使用for-of(这意味着您不必拥有genForLoop 标识符):

for (const value of genBubble(tempArray)) {
  console.log(value.join(","));
}

但是(我已经好几年没有做过冒泡排序了)我相信你的内部循环终止需要j &lt; arr.length - 1,而不仅仅是j &lt; arr.length - i - 1。我隐约记得内部循环可以更短,但显然不是那样。

现场示例:

function swap(arr, i1, i2) {
  const t = arr[i1];
  arr[i1] = arr[i2];
  arr[i2] = t;
}
function* genBubble(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - 1; j++) {
      yield arr; // returning arr after every iteration
      if (arr[j] > arr[j + 1]) {
        swap(arr, j, j + 1); // removed swap for brevity
      }
    }
  }
}
const tempArray = [3, 5, 8, 4, 1, 9, -2];

for (const value of genBubble(tempArray)) {
  console.log(value.join(","));
}
.as-console-wrapper {
  max-height: 100% !important;
}

你的外循环条件应该是&lt; arr.length,而不是&lt; arr.length - 1

【讨论】:

  • 谢谢,但真的需要arr.length 吗? arr.length - 1 因为我们不需要检查冒泡排序中的最后一次迭代,因为它已经在正确的位置,对吧?
  • 我确实点击了刷新。我正在考虑“您的外循环条件应该是
  • @theprogrammer - 是的,不知怎的,我搞砸了 sn-p。我现在已经修复了它和答案。不过,我认为您的 inner 循环终止条件不正确。当然,j &lt; arr.length - i - 1 的结果不正确,j &lt; arr.length - 1 的结果正确。多年来我没有做过冒泡排序,我认为你可以在那里做一个选择,但显然不是那个。但我认为,主要问题根本不是冒泡排序的实现,而是如何使用生成器。
  • 是的,我认为有多种方法可以通过在外部或内部循环中交换边缘情况来编写冒泡排序。
猜你喜欢
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 2018-08-16
  • 2016-12-02
  • 2017-11-18
  • 2018-01-23
  • 2016-08-19
相关资源
最近更新 更多