【问题标题】:Check if an array is descending, ascending or not sorted?检查数组是降序、升序还是未排序?
【发布时间】:2017-07-08 20:57:14
【问题描述】:

我刚开始使用 javascript 进行编程,我需要练习一些问题来获得代码构建逻辑的 EXP。 我收到了这个家庭作业问题,但由于某种原因我无法让它发挥作用,即使它对我来说似乎是“合乎逻辑的”。 使用循环检查数组是降序、升序还是未排序。

我只是一个菜鸟,所以请尝试帮助我解决这个问题,因为我只需要在学习中循环(: 这是我写的代码:

        var array = [1, 2, 3, 7 ];
        var d = 0;
        var c =0 ;
        var b = 1;
        var a = 0;
        for (var i = 1; i <= array.length; i++)
            {
                if (array[c]<array[b] && a!== -1  ){
                   d = -1;
                   c =c+1;
                   b = b+1;
                   if(c==array.length){
                    console.log("asc");
                     break;
                   }else{
                     continue;
                }

                } else if (array[c]>array[b] && d!==-1 ){
                           a = -1;
                           d= d+1;
                           b = b+1;
                    if(i=array.length){
                    console.log("dsc");
                    break;
               }else{continue;}

               } else{

                    console.log("unsorted array");
                    break;
                }

            }

【问题讨论】:

  • FWIW,JavaScript 中的数组是基于 0 索引的。
  • [1, 1] 是升序吗? [42] 是什么?

标签: javascript


【解决方案1】:

Array.prototype.every 将它的谓词传递给一个索引,您可以使用它来获取一个元素的前驱:

function isAscending(arr) {
    return arr.every(function (x, i) {
        return i === 0 || x >= arr[i - 1];
    });
}

在这里,我们正在检查每个项目 (x) 是否大于或等于它之前的项目 (arr[i - 1]) 或之前没有项目 (i === 0)。

&gt;= 翻转为&lt;= 以获得isDescending

【讨论】:

    【解决方案2】:

    “使用循环检查数组是降序、升序还是未排序”

    // define the array
    var array = [1,2,3,7];
    
    // keep track of things
    var isDescending = true;
    var isAscending = true;
    
    // we're looking ahead; loop from the first element to one before the last element
    for (var i=0, l=array.length-1; i<l; i++)
    {
    
       ////////////////////////////////////////////////////////////
    
       // log to the console to show what's happening for each loop iteration
    
       // this is the ith iteration 
       console.log("loop iteration %s", i);
    
       // breaking isDescending down:
       // is this value greater than the next value?
       console.log("A: (%s > %s) = %s", array[i], array[i+1], (array[i] > array[i+1]));
    
       // have all values been descending so far?
       console.log("B: isDescending: %s", isDescending);
    
       // if this value is greater than the next and all values have been descending so far, isDescending remains true. Otherwise, it's set to false.
      console.log("are A and B both true? %s", (isDescending && (array[i] > array[i+1])));
    
       // add a line break for clarity
       console.log("");
    
       ////////////////////////////////////////////////////////////
    
    
       // true if this is greater than the next and all other so far have been true
       isDescending = isDescending && (array[i] > array[i+1]);
    
       // true if this is less than the next and all others so far have been true
       isAscending = isAscending && (array[i] < array[i+1]);
    
    }
    
    if (isAscending)
    {
      console.log('Ascending');
    }
    else if (isDescending) 
    {
      console.log('Descending');
    }
    else
    {
      console.log('Not Sorted');
    }

    【讨论】:

    • 好的,这看起来很接近我能理解的东西。它没有功能,所以这对我来说很棒。你能试着解释一下这个代码行吗?这里发生了什么? " isDescending = isDescending && (array[i] > array[i+1]); isAscending = isAscending && (array[i]
    • 当然,首先我们将isDesdending 设置为truevar isDescending = true;。对于循环的每次迭代,检查此数组索引处的值array[i] 是否大于下一个值array[i+i]。如果是,(array[i] &gt; array[i+i]) 就是true。现在我们有isDescending = (true &amp;&amp; true),所以isDescending = true。如果不是真的,我们有isDescending = (true &amp;&amp; false) 所以isDescending = false。如果 isDescending 在遍历整个数组后保持为真,则数组按降序排序。
    • 哇,这让我大吃一惊。非常简单优雅!你刚刚让我对某种新型算法思维敞开了心扉。
    【解决方案3】:

    这是一个需要某种循环的问题,有几个if 语句,因为有几种情况需要处理:

    1. 数组为空或只有一个元素。
    2. 数组中的所有项都是相等的
    3. 数组升序 - 2 个元素之间的 delta > 0,但某些 delta 可能为 0
    4. 数组正在下降 - 2 个元素之间的 delta
    5. 未排序 - 一些增量大于 0,而一些小于 0

    根据问题中排序的定义方式,案例1和2也可能被视为未排序

    function findSortOrder(arr) {
      if(arr.length < 2) { // case 1
        return 'not enough items'; // can also be 'unsorted'
      }
      
      var ascending = null;
      var nextArr = arr.slice(1); // create an array that starts from the 2nd element of the original array
    
      for(var i = 0; i < nextArr.length; i++) {
        if (nextArr[i] === arr[i]) { // neutral - do nothing
        } else if(ascending === null) { // define the the direction by the 1st delta encountered
          ascending = nextArr[i] > arr[i];
        } else if (ascending !== nextArr[i] > arr[i]) { // case 5
          return 'unsorted';
        }
      }
      
      if(ascending === null) { // case 2
        return 'all items are equal'; // can also be 'unsorted'
      }
      
      return ascending ? 'ascending' : 'descending'; // cases 3 & 4
    }
    
    console.log(findSortOrder([1])); // case 1
    
    console.log(findSortOrder([1, 1, 1, 1])); // case 2
    
    console.log(findSortOrder([1, 1, 2, 3, 7, 7])); // case 3
    
    console.log(findSortOrder([7, 2, 2, 1])); // case 4
    
    console.log(findSortOrder([7, 2, 1, 3, 2, 1])); // case 5

    【讨论】:

    • 为什么是nextArr[i] - arr[i] === 0 而不是nextArr[i] === arr[i]&gt; 也是如此。
    • @Ryan - 我处于“三角洲”的心态:) 我已经根据你的建议更新了代码。谢谢。
    【解决方案4】:

    您可以使用第二个元素的副本并检查前一个元素的所需排序顺序。

    function checkArray(array) {
        var aa = array.slice(1);
        if (!aa.length) {
            return "Just one element";
        }
        if (aa.every((a, i) => array[i] > a)) {
            return "Ascending";
        }
        if (aa.every((a, i) => array[i] < a)) {
            return "Descending";
        }
        return "Unsorted";
    }
    
    console.log(checkArray([1, 2, 3, 4, 5]));
    console.log(checkArray([5, 4, 3, 2, 1]));
    console.log(checkArray([3, 1, 4, 2, 5]));
    console.log(checkArray([42]));

    【讨论】:

      【解决方案5】:
      function isAscending(arr) { 
        return arr
          .slice(1)
          .every((num,i) => num >= arr[i]); 
      }
      
      console.log(isAscending([1,2,3])); // true
      console.log(isAscending([12,38,25])); // false
      console.log(isAscending([103,398,52,629])); // false
      
      1. arr.slice(1) --> 允许我们从索引 1 而不是 0 开始迭代
      2. 我们将使用“every”迭代“arr”并将当前的“num”与之前使用“arr[i]”的“num”进行比较

      【讨论】:

        【解决方案6】:
        function findOrder(array) {
            var asc = true;
            var desc = true;
            if(array.length < 2){
                return 'array is too small'
            }
            for(var i=1, len=array.length;i<len;i++){
                //if current element is bigger than previous array is not descending
                if(array[i]>array[i-1]){
                    desc = false;
                //if current element is smaller than previous array is not ascending
                }else if(array[i]<array[i-1]){
                    asc = false;
                }
        
                if(!asc && !desc){
                    return 'not sorted'
                }
            }
        
            if(asc && desc){
                return 'array values are equal'
            }else if (asc){
                return 'array is ascending'
            }else {
                return 'array is descending'
            }
        }
        

        【讨论】:

          【解决方案7】:

          实际上,我们可以通过创建像 natureOf 这样的 Array 方法来做更多事情,它可以告诉我们更多关于数组性质的信息,而不仅仅是升序、降序或平坦。 Array.natureOf() 应该给我们一个介于 -1 和 1 之间的值。如果是 -1,则数组完全下降,当然 1 表示完全上升。中间的任何值都会给我们数组的倾斜度。正如您所猜测的那样,0 意味着完全随机或平坦。 (如果还需要的话,插入逻辑来区分随机和扁平是相当容易的)

          Array.natureOf = function(a){
                             var nature = a.reduce((n,e,i,a) => i && a[i-1] !== e ? a[i-1] < e ? (n.asc++, n)
                                                                                               : (n.dsc++, n)
                                                                                  : n, {asc:0, dsc:0});
                             return (nature.asc - nature.dsc) / (a.length-1);
                           };
          var arr = [1,2,3,4,5,6,7,8,9,10,7,11,13,14,15],
              brr = Array.from({length:2000000}, _ => ~~(Math.random()*1000000000));
          
          console.log(`The nature of "arr" array is ${Array.natureOf(arr)}`);
          console.log(`The nature of "brr" array is ${Array.natureOf(brr)}`);

          【讨论】:

            【解决方案8】:
            function isAscending(arr = []) {
              for (let i = 0; i < arr.length; i++) {
                if (arr[i + 1] <= arr[i]) {
                  return false;
                }
              }
              return true;
            }
            

            【讨论】:

            • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 此代码回答问题的附加上下文可提高其长期价值.
            【解决方案9】:
              console.log(checkSort([1, 2, 3, 3, 4, 5]));
              console.log(checkSort([5, 4, 3, 2, 1, 1]));
              console.log(checkSort([2, 5, 8, 9, 4, 6]));
            
              function checkSort(arr){
            
                var isDescending, isAscending;
                isDescending = isAscending = true;
            
                const len = arr.length - 1;
            
                for (var index = 0 ; index < len ; index++){
                  if(isAscending)
                  isAscending = arr[index] <= arr[index + 1];// '<=' so as to check for same elements
            
                  if(isDescending)
                  isDescending = arr[index] >= arr[index + 1];//'<=' so as to check for same elements
                }
            
                var result = "Array is ";
                
                if (isAscending)
                return result.concat("sorted in ascending order");
                
                if (isDescending)
                return result.concat("sorted in descending order");
                
                return result.concat("not sorted");
            

            【讨论】:

              猜你喜欢
              • 2018-09-23
              • 1970-01-01
              • 1970-01-01
              • 2021-03-27
              • 2018-04-25
              • 1970-01-01
              • 1970-01-01
              • 2022-01-10
              • 2021-12-20
              相关资源
              最近更新 更多