【问题标题】:JavaScript sequence using for loop or switch statement使用 for 循环或 switch 语句的 JavaScript 序列
【发布时间】:2017-06-03 03:34:48
【问题描述】:

我遇到了一个问题以及如何解决它。请注意,我对 JavaScript 比较陌生,感觉问题好像我把它复杂化了。

问题:

给定一个整数序列作为一个数组,确定是否可以通过从数组中删除不超过一个元素来获得一个严格递增的序列。

例子

对于序列 = [1, 3, 2, 1],输出应该是 almostIncreasingSequence(sequence) = false;

这个数组中没有一个元素可以被移除以获得严格递增的序列。

对于序列 = [1, 3, 2],输出应该是 almostIncreasingSequence(sequence) = true.

您可以从数组中删除 3 以获得严格递增的序列[1, 2]。或者,您可以删除 2 以获得严格递增的序列[1, 3]

感谢您的所有 cmets!我想将其更新为一个更好的问题,并通知您如果有人想检查它并查看是否有更清洁的方法来放置它,我已经找到了解决方案。 :)

function almostIncreasingSequence(sequence) {    
  if(sequence.length == 2) return true;
  var error = 0;
  for(var i = 0; i < sequence.length - 1; i++){
    if(sequence[i] >= sequence[i+1]){
      var noStepBack = sequence[i-1] && sequence[i-1] >= sequence[i+1];
      var noStepFoward = sequence[i+2] && sequence[i] >= sequence[i+2];
      if(i > 0 && noStepBack && noStepFoward) {
        error+=2;
      }else{
        error++;
      }
    }
    if(error > 1){
      return false;
    }
  }
  return true;
}

【问题讨论】:

  • 欢迎来到 Stack Overflow。请阅读:stackoverflow.com/help/mcve
  • 请注意问题如何陈述“严格递增的序列”,它没有指定它是如何增加的,所以你可以有[1, 2, 3, 5, 8, 13],它是有效的,我给你的提示是尝试看看是否差异是正数而不是特定数字
  • 这个看似简单的问题似乎很难正确解决……
  • @Twisty 谢谢你!我继续阅读更多最佳问题发布实践,希望我的下一个问题能达到目标!再次感谢

标签: javascript arrays sequences


【解决方案1】:

想想你的代码是什么:

sequence[i+1] - sequence[i] !== 1, variable++;

适用于以下数组:[1,2,3,8,8]

从问题描述来看,不清楚程序必须删除一个字符。但如果是这种情况,下面的代码应该可以做到。

function canGetStrictlyIncreasingSeq(numbers) {
  var counter = 0;
  var lastGreatestNumber = numbers[0];
  for (var i = 1; i < numbers.length; i++) {
    if (lastGreatestNumber >= numbers[i]) {
      counter++;
      lastGreatestNumber = numbers[i];
    } else {
      lastGreatestNumber = numbers[i];
    }
  }
  if (counter <= 1)
    return true;
  return false;
}

var nums1 = [1, 2, 3, 4, 5]; //true
var nums2 = [1, 2, 2, 3, 4]; //true
var nums3 = [1, 3, 8, 1, 9]; //true
var nums4 = [3, 2, 5, 6, 9]; //true
var nums5 = [3, 2, 1, 0, 5]; //false
var nums6 = [1, 2, 2, 2, 3]; //false
var nums7 = [1, 1, 1, 1, 1]; //false
var nums8 = [1, 2]; //true
var nums9 = [1, 2, 2]; //true
var nums10 = [1, 1, 2, 3, 4, 5, 5]; //false
var nums11 = [10, 1, 2, 3, 4, 5]; //true
var nums12 = [1, 2, 3, 4, 99, 5, 6]; //true


console.log(canGetStrictlyIncreasingSeq(nums1));
console.log(canGetStrictlyIncreasingSeq(nums2));
console.log(canGetStrictlyIncreasingSeq(nums3));
console.log(canGetStrictlyIncreasingSeq(nums4));
console.log(canGetStrictlyIncreasingSeq(nums5));
console.log(canGetStrictlyIncreasingSeq(nums6));
console.log(canGetStrictlyIncreasingSeq(nums7));
console.log(canGetStrictlyIncreasingSeq(nums8));
console.log(canGetStrictlyIncreasingSeq(nums9));
console.log(canGetStrictlyIncreasingSeq(nums10));
console.log(canGetStrictlyIncreasingSeq(nums11));
console.log(canGetStrictlyIncreasingSeq(nums12));

【讨论】:

  • 这不适用于许多测试用例,包括1,2,3,4,5
  • 我已更新代码并使其可运行。还增加了一些测试用例,包括1,2,3,4,5。
  • 这对某些测试不起作用,包括: 输入:序列:[10, 1, 2, 3, 4, 5] 输出:false 预期输出:true 输入:序列:[1, 2、3、4、99、5、6] 输出:false 预期输出:
  • 再次更新。也许社区可以帮助我们找到更多的案例? :)
【解决方案2】:

让我们退后一步思考一下这个问题:“给定一个整数序列作为一个数组”——我们正在处理数据数组......但你已经知道了。

“确定是否有可能获得严格递增的序列”好的,我们需要做一些检查有效序列的东西。

“通过从数组中删除不超过一个元素。”因此我们可以尝试一个接一个地提取每个元素,如果至少一个结果数组是连续的,那么它是可能的。

现在我们有两个小问题,而不是一个大问题

首先,我们正在处理数组,因此请利用 JavaScript 的内置数组函数来简化操作。在下面,我们使用 'every()'、'forEach()'、'splice()'、'push()' 和 'some()' 你可以在这里阅读它们是如何工作的 https://www.w3schools.com/jsref/jsref_obj_array.asp 时间不长非常值得您花时间。

让我们处理第一个问题:确定数组是否是顺序的。下面的函数就是这样做的

function checkSequence(inputArray){
    return inputArray.every(function(value, index, arr){
        if (index == 0  && value < arr[index + 1]) {return true}
        else if (index < arr.length  && value < arr[index + 1] && value > arr[index - 1]) {return true}
        else if (index = arr.length - 1 && value > arr[index - 1]) {return true}
        else {return false}
    });
}

它接受一个输入数组,并使用一个名为 every() 的 Array 内置函数,该函数对数组中的每个元素运行测试 如果所有元素都测试为真,则返回“真”。我们的测试期望第一个元素总是低于第二个 任何给定元素大于前一个,小于下一个,最后一个元素大于倒数第二个 如果任何元素不满足此测试,则整个返回 false 现在我们有一种方法可以看到数组是顺序的,这将使下一部分变得更容易

现在我们创建另一个函数来提取单个元素并查看是否有任何工作

function isPossible(input){
    var results = []; //we will store our future results here
    input.forEach(function(value, index, arr){
        copy = Array.from(arr); //we work on a copy of 'arr' to avoid messing it up (splice mangles what you give it, and we need the un-maimed version for later iterations)
        copy.splice(index, 1); //remove an element from copy (a copy of 'arr')      
        results.push(checkSequence(copy)); //see if it is still in sequence
    });
    return results.some(function(value){return value});
}

我们首先创建一个数组,将每次尝试的结果存储到数组“results”中,稍后我们将使用它。 然后,我们采用提供的数组“输入”并使用“forEach()”,它对数组中的每个元素执行一个函数。 对于每个元素,我们创建一个新数组,并从中删除该元素,然后运行“checkSequence()” 我们之前在它上面做的函数,最后把结果存入results数组中。

当 forEach 完成后,我们获取结果数组并在其上使用 'some()',其工作方式与 'every()' 一样 只有当至少一个值为真时才返回真

现在,您只需调用 isPossible(your_array) 即可解决问题

【讨论】:

  • 目前对[1,-1] 失败,但对[1][1,-1,0] 有效
  • 感谢@Thomas Skubicki 的详细回复!我确实运行了您共享的代码并返回了一些错误。见下文: 输入:sequence: [1, 3, 2] 输出:false 预期输出:true 输入:sequence: [10, 1, 2, 3, 4, 5] 输出:false 预期输出:true
【解决方案3】:

考虑到 Patrick Barr 的建议并假设 es6 和箭头函数都很好,这个使用 Array.prototype.filter 的解决方案可以工作。过滤器本身将返回应删除以满足问题条件的元素数组:

更新

function isSequential(array) {
    return array && array.length > 0 ? array.filter((x,i) => x >= array[i + 1] || array[i + 1] <= array[i - 1]).length < 2 : false;
}


console.log(isSequential([1]));
console.log(isSequential([1,2,4,5,6]));
console.log(isSequential([1,2,2,3,4,5,6]));
console.log(isSequential([1,4,3,2,5,6]));
console.log(isSequential([1,2,3,4,5,6]));
console.log(isSequential([1,2,0,3,4]));
console.log(isSequential([1,1]));
console.log(isSequential([1,2,0,1,2]));
console.log(isSequential([1,2,3,1,2,3]));
console.log(isSequential([]));
console.log(isSequential([1,0,0,1]));
console.log(isSequential([1,2,6,3,4])); //should be true, but return false

【讨论】:

  • @le_m 感谢这个伟大的测试用例!您对如何改进我的功能有什么建议吗?将不胜感激。我只能假设更改过滤器以检查 prev 元素。查看更新的代码。
  • 目前不知道如何优雅地解决这个问题。我建议将isSequential([1,2,6,3,4]); // should be true 也包含在一个测试用例中,但它目前失败了。
  • 感谢您的评论!该代码虽然未能通过几个测试,请参阅: 输入:序列:[10, 1, 2, 3, 4, 5] 输出:false 预期输出:true 输入:序列:[123, -17, -5, 1, 2 , 3, 12, 43, 45] 输出:false 预期输出:true
  • @Almost_Ashleigh 我正在考虑一个更好的解决方案,如果我有东西会通知我。这个问题变得比初看起来更复杂。
  • @StanislavKvitash 谢谢!是的,我绝对应该进一步解释问题以澄清我进行更新的原因。 :)
猜你喜欢
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 2015-10-30
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多