【问题标题】:Check if an array is sorted, return true or false检查数组是否排序,返回真或假
【发布时间】:2013-10-27 19:20:26
【问题描述】:

我正在编写一个简单的程序,如果数组排序为 false,则返回 true,并且我在 Eclipse 中不断收到异常,但我不知道为什么。我想知道是否有人可以查看我的代码并解释为什么我得到一个数组越界异常。

public static boolean isSorted(int[] a) 
{
    int i;
    for(i = 0; i < a.length; i ++);{
        if (a[i] < a[i+1]) {
            return true;
        } else {
            return false;   
        }
    }
}
public static void main(String[] args)
{
    int ar[] = {3,5,6,7};
    System.out.println(isSorted(ar));   
}

【问题讨论】:

  • 运行你的代码。您有 4 个条目,应该很简单。 i 在某个时候会等于 3,a[3+1] 会尝试访问什么?
  • 检查你的索引范围
  • 另请注意,代码并没有按照你说的做。如果有两个或多个连续的有序元素,则返回 true,但不一定全部。
  • 提示从 i=1 开始循环,如果长度 >1 则比较更低

标签: java arrays sorting traversal


【解决方案1】:

让我们看一下您构建的循环的更简洁版本:

for (i = 0; i < a.length; i++); { 
    if (a[i] < a[i + 1]) {
        return true;
    }
    else {
        return false;
    }
}

我应该首先指出原始循环中的语法错误。即,在开始循环体的花括号 ({) 之前有一个分号 (;)。应该删除该分号。 另请注意,我重新格式化了代码的空白以使其更具可读性。

现在让我们讨论一下循环内部发生了什么。循环迭代器i 开始于0 并结束于a.length - 1。由于i 用作数组的索引,因此指出a[0] 是数组的第一个元素而a[a.length - 1] 是数组的最后一个元素是有意义的。但是,在循环的主体中,您也编写了i + 1 的索引。这意味着如果i 等于a.length - 1,则您的索引等于a.length,这超出了数组的范围。

函数isSorted 也有相当大的问题,因为它第一次返回true a[i] &lt; a[i+1] 而第一次不返回false;因此,它实际上并不检查数组是否已排序!相反,它只检查前两个条目是否已排序。

一个逻辑相似但检查数组是否真的排序的函数是

public static boolean isSorted(int[] a) {
// Our strategy will be to compare every element to its successor.
// The array is considered unsorted
// if a successor has a greater value than its predecessor.
// If we reach the end of the loop without finding that the array is unsorted,
// then it must be sorted instead.

// Note that we are always comparing an element to its successor.
// Because of this, we can end the loop after comparing 
// the second-last element to the last one.
// This means the loop iterator will end as an index of the second-last
// element of the array instead of the last one.
    for (int i = 0; i < a.length - 1; i++) {
        if (a[i] > a[i + 1]) {
            return false; // It is proven that the array is not sorted.
        }
    }

    return true; // If this part has been reached, the array must be sorted.
}

【讨论】:

  • 最坏情况复杂度是 O(n)。假设数据是从正态分布中随机选择的,平均时间复杂度是多少?真的是 O(1) 吗?似乎是一堆递减的几何级数,其总和是另一个几何级数,当 n 接近 n → ∞ 因此 O(1) 时它只给出 4。这是真的吗?
  • @nader 觉得有道理,在每个数据点,早游的变化是 0.5,所以平均时间复杂度必须远小于 O(n)
【解决方案2】:

对于使用 Java 8 及更高版本的任何人,这里有一个简单的单行:

public static boolean isSorted(int[] array) {
    return IntStream.range(0, array.length - 1).noneMatch(i -> array[i] > array[i + 1]);
}

或逻辑等效的替代方案:

public static boolean isSorted(int[] array) {
    return IntStream.range(0, array.length - 1).allMatch(i -> array[i] <= array[i + 1]);
}

【讨论】:

  • 第一个逻辑不正确.. new int[]{1, 2, 4, 5, 6, 1} 最后一个元素失败。
  • @Moshiour 非常感谢您指出这一点。 anyMatch 应该是 noneMatch
  • 欢迎朋友 :)
【解决方案3】:

使用此表达式a[i+1],您将超出数组的末尾。

如果您必须与下一个元素进行比较,请尽早停止迭代 1 元素(并消除分号,Java 会将其解释为您的 for 循环体):

// stop one loop early ---v       v--- Remove semicolon here
for(i = 0; i < a.length - 1; i ++){

【讨论】:

    【解决方案4】:
    int i;
    for(i = 0; i < a.length - 1 && a[i] < a[i+1]; i++){}
    return (i == a.length - 1);
    
    • 只访问数组元素,结束条件的最后一部分不访问 如果第一部分为假,则处理
    • 在第一个未排序的元素上停止

    【讨论】:

      【解决方案5】:

      要检查数组是否排序,我们可以比较数组中的相邻元素。

      检查nulla.length == 0的边界条件

      public static boolean isSorted(int[] a){    
      
          if(a == null) {
              //Depends on what you have to return for null condition
              return false;
          }
          else if(a.length == 0) {
              return true;
          }
          //If we find any element which is greater then its next element we return false.
          for (int i = 0; i < a.length-1; i++) {
              if(a[i] > a[i+1]) {
                  return false;
              }           
          }
          //If array is finished processing then return true as all elements passed the test.
          return true;
      }
      

      【讨论】:

        【解决方案6】:

        a[i+1] i == a.length 会给你这个错误。

        例如,在长度为 10 的数组中,您有 0 到 9 个元素。

        a[i+1]i 为9 时,将显示a[10],超出范围。

        修复:

        for(i=0; i < a.length-1;i++)
        

        此外,您的代码不会检查整个数组,只要调用 return,检查循环就会终止。 您只是检查第一个值,并且只检查第一个值。

        并且,您的 for 循环声明后有一个分号,这也会导致问题

        【讨论】:

        • 啊啊啊!我现在明白了,谢谢你的帮助
        【解决方案7】:

        您不应使用a[i+1],因为该值可能会或可能不会超出数组。

        例如:

        A = {1, 2, 3}
        // A.length is 3.
        for(i = 0; i < a.length; i ++) // A goes up to 3, so A[i+1] = A[4]
        

        要解决此问题,只需提前停止循环。

        int i;
        for(i = 0; i < a.length - 1; i ++);{
        
            if (a[i] < a[i+1]) {
        
                return true;
            }else{
                return false;
        
            }
        
        }
        

        【讨论】:

        • int 数组不能为空。此外,虽然您的代码解决了异常,但它实际上并没有实现该方法所要实现的目标
        【解决方案8】:

        降序数组也被排序。为了同时考虑升序和降序数组,我使用以下内容:

        public static boolean isSorted(int[] a){
            boolean isSorted = true;
            boolean isAscending = a[1] > a[0];
            if(isAscending) {
                for (int i = 0; i < a.length-1; i++) {
                    if(a[i] > a[i+1]) {
                        isSorted = false;
                        break;
                    }           
                }
            } else {//descending
                for (int i = 0; i < a.length-1; i++) {
                    if(a[i] < a[i+1]) {
                        isSorted = false;
                        break;
                    }           
                }  
            }    
            return isSorted;
        }
        

        【讨论】:

          【解决方案9】:
          boolean checkElements(int arr[],  int first, int last) {
              while(arr.length > first) {
                  if(arr[i] > arr[last-1]) {
                      if(arr[i] > arr[i+1])
                          return checkElements(arr, first+1, first+2);;
                      return false;
                  }else {
                      if(arr[i] < arr[i+1])
                          return checkElements(arr, first+1, first+2);
                      return false;
                  }
              }
              return true;
          }
          

          【讨论】:

          • 你应该提供一些关于代码的解释,这样人们就不必解码它。例如,i 是什么?你在哪里声明的?您正在验证升序或降序排序?尽量不要只用代码来回答。查看How to Answer了解更多详情。
          【解决方案10】:

          如果要检查数组是按DESC还是ASC排序的:

          boolean IsSorted(float [] temp)
          {
              boolean result=true,result2=true;
              for (int i = 0; i < temp.length-1; i++)  
                  if (temp[i]< temp[i + 1]) 
                          result= false;
          
              for (int i = 0; i < temp.length-1; i++)  
                  if (temp[i] > temp[i + 1])   
                      result2= false;
          
              return result||result2;
          }
          

          【讨论】:

            【解决方案11】:
            bool checkSorted(int a[], int n) {
              for (int i = 1; i < n-1; i++) {
                if (a[i] > a[i-1]) {
                  return false;
                }
              }
              return true;
            }
            

            【讨论】:

            • 口头解释通常很有帮助
            • 我们简单地检查相邻元素 (a[i] > a[i-1] ) 并相应返回
            【解决方案12】:
            public static boolean isSorted(int[] a) 
            {
                int i,count=0;
                for(i = 0; i < a.length-1; i++);{
                    if (a[i] < a[i+1]) {
                        count=count+1;
                    }  
                    }
                if(count==a.length-1)
                    return true;
                else
                    return false;
            }
            public static void main(String[] args)
            {
                int ar[] = {3,5,6,7};
                System.out.println(isSorted(ar));   
            }
            

            这里是检查数组是否已排序的代码,如果已排序则返回true,否则返回false。希望您理解方法。

            【讨论】:

              【解决方案13】:

              如果一个数组不是按升序或降序排列的,那么它就不会被排序。

              我将检查相邻元素是否已排序。 如果任何元素小于其前一个元素,则不按升序排序。

              public static boolean isAscendingOrder(int[] a)
              {  
                  for ( int i = 0; i < a.length - 1 ; i++ ) {
                      if ( a[i] > a[i+1] )
                        return false;
                  }
                  return true;
              }
              
              
              // Same with Desending order
              public static boolean isDescendingOrder(int[] a)
              {  
                  for ( int i = 0; i < a.length - 1 ; i++ ) {
                      if ( a[i] < a[i+1] )
                        return false;
                  }
                  return true;
              }
              
              
              public static boolean isSorted(int[] a)
              {  
                 return isAscendingOrder(a) || isDescendingOrder(a);
              }
              

              此函数检查数组是否按排序顺序排列,无论其顺序如何,即升序或降序。

              【讨论】:

              • 你能解释一下你的答案吗?
              • 欢迎来到 Stack Overflow!虽然这段代码 sn-p 可以解决问题,包括说明 如何为什么 这解决了问题would really help 以提高您的帖子质量。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。
              • 欢迎堆栈溢出 :-) 请看How to Answer。您应该提供一些信息为什么您的代码可以解决问题。纯代码答案对社区没有用处。
              • 条件( a[i] > a[i+1] )在排序数组中始终为假。从任何排序的数组中选择任何位置并与任何其他位置交换,条件将在您放置/删除项目的位置为真。
              【解决方案14】:

              Array.prototype.every

              every() 方法测试数组中的所有元素是否通过提供的函数实现的测试。

              arr.every(function (a, b) {
                return a > b;
              });
              
              var arr = [1,2,3] // true
              
              var arr = [3,2,1] // false
              

              【讨论】:

              • 注意到这是一个关于 java 的问题,但是查看 .every() 的 src 会有所启发 ;)
              • 这个答案是错误的,不仅因为它适用于js,还因为它没有做它应该做的事情。 every 函数一次只测试一个元素,所以 arg b 在这种情况下是元素 a 的索引。所以提供的函数只测试arr[i] &gt; i。对于[5, 3, 5],它返回true,而对于[0, 1, 2],它返回false
              猜你喜欢
              • 2019-07-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-09-28
              • 2015-02-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多