私は簡単なプログラムを書いていますが、配列がソートされている場合はtrueを返し、それ以外の場合はfalseを返します。誰かが私のコードを見て、なぜ範囲外の例外を取得しているのかを説明してくれるのではないかと思っていました。
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));
}
作成したループのよりクリーンなバージョンを見てみましょう。
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
には、a[i] < a[i+1]
が初めてtrueを返し、そうでないときにfalseを返すため、かなりの問題があります。 ergoは、配列がまったくソートされているかどうかを実際にチェックしません!むしろ、最初の2つのエントリがソートされているかどうかのみをチェックします。
同様のロジックを持つが、配列が実際にソートされているかどうかをチェックする関数は
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.
}
この式では、a[i+1]
、あなたはアレイの端から走っています。
次の要素と比較する必要がある場合は、反復1要素を早期に停止します(そしてJavaはfor
ループ本体として解釈されるセミコロンを削除します):
// stop one loop early ---v v--- Remove semicolon here
for(i = 0; i < a.length - 1; i ++){
int i;
for(i = 0; i < a.length - 1 && a[i] < a[i+1]; i++){}
return (i == a.length - 1);
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]);
}
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ループ宣言の後にセミコロンを持っていますが、これも問題を引き起こしています
配列がソートされているかどうかを確認するために、配列内の隣接する要素を比較できます。
null
&a.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;
}
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;
}
}
public static boolean isSorted(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){
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;
}
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;
}