1

このプログラムは、単に配列から重複を排除することになっています。しかし、remove メソッドの 2 番目の for ループは範囲外の例外をスローしていました。私は見ていましたが、それがどのようになるかわかりませんでした。そのため、配列のサイズを 1 増やして、最後に追加の 0 を追加するという唯一の欠点で機能させるようにしました。

驚いたことに、tracker[] のサイズを 10 から 11 に増やすと、プログラムは 0 から 9 までのすべての数値を出力します。これらの数値はどこから来て、なぜこの問題が発生するのですか?

import java.util.*;
class nodupes 
{
    public static void main(String[] args) 
    {   

        int[] dataset = new int[10];


        //getting the numbers
        for (int i = 0; i <= 9 ; i++)
        {
            Scanner input = new Scanner(System.in);
            System.out.println("Enter a one digit number");
            dataset[i] = input.nextInt();
        }

        int[] answer = (eliminateduplicates(dataset));
        System.out.println(Arrays.toString(answer));
    }

    public static int[] eliminateduplicates(int[] numbers)
    {

        boolean[] tracker = new boolean[11];
        int arraysize = 1; 
        for(int k = 0; k <= 9; k++)
        {

            if(tracker[numbers[k]] == false)
            {
                arraysize++;
                tracker[numbers[k]] = true;
            }

        }
        int[] singles = new int[arraysize];

        for(int l = 0; l <= arraysize; l++)
        {
            if(tracker[l] == true)
            {
                singles[l] = l;

            }


        }

        return singles;
    }
}    

この部分で例外が発生していました

     if(tracker[l] == true)

ただし、トラッカーのサイズが10の場合のみ。11の場合、[0,1,2,3,4,5,6,7,8,9]を印刷するだけです

編集: arraysize = 1 はデバッグからの保留でした。元々は 0 でした。

編集:修正しましたが、配列が完全にいっぱいになるはずなのに、最後に 0 があります。

public static int[] eliminateduplicates(int[] numbers)
{

    boolean[] tracker = new boolean[10];
    int arraysize = 0; 

    for(int k = 0; k < numbers.length; k++)
    {

        if(tracker[numbers[k]] == false)
        {
            arraysize++;
            tracker[numbers[k]] = true;
        }

    }
    int[] singles = new int[arraysize];
    int counter = 0;

    for(int l = 0; l < arraysize; l++)
    {
        if(tracker[l] == true)
        {
            singles[counter] = l;
            counter++;
        }


    }

    return singles;
}
4

5 に答える 5

1

配列は 0 から始まるため、配列サイズは一意の数値の数よりも 1 大きくなり、最後のループが何度も繰り返されます。つまり、"l" (文字 l -- 別の変数名を使用してみてください) は、10 個の一意の番号があり、トラッカーにアイテム 0 ~ 10 しかない場合、したがって範囲外の例外である場合に 11 になります。宣言を int arraysize = 0; に変更してみてください。

于 2011-12-01T02:59:42.077 に答える
1

再び <= に敗北

for(int l = 0; l <= arraysize; l++)

10 の配列サイズは 0 ~ 9 を意味し、このループは 0 ~ 10 になります。

数字がどこから来ているかについては、

singles[l] = l;

カウント値を singles フィールドに割り当てているため、singles[1] には 1 が割り当てられます。

于 2011-12-01T03:01:36.820 に答える
0

コレクションを使用しないという制限がない場合は、これを試すことができます。

public class NoDupes {
    public static void main(String[] args) {
        Integer[] dataset = new Integer[10];
        for (int i = 0; i < 10; i++) {
          Scanner input = new Scanner(System.in);
          System.out.println("Enter a one digit number");
          dataset[i] = input.nextInt();
        }
        Integer[] arr = eliminateduplicates(dataset);
        for (Integer integer : arr) {
           System.out.println(integer);
        }
    }

     public static Integer[] eliminateduplicates(Integer[] numbers) {
        return new HashSet<Integer>(Arrays.asList(numbers)).toArray(new Integer[]{});
     }
}

あなたの質問に答えるために、あなたの最終的なループは、サイズよりも 1 インデックス多くなっています。

于 2011-12-01T03:07:52.647 に答える
0

Java の配列の有効なインデックスの範囲は[0, SIZE)、つまり です。0 から までarraysize-1

例外が発生する理由は、ループで 0 からarraysize inclusively まで反復しているために、1 インデックスが遠すぎるためです。

for(int l = 0; l <= arraysize; l++)

したがってif(tracker[l] == true)、最後の反復でに到達すると、l等しくarraysizeなりtracker[l]、配列の範囲外になります。これは、ループ条件を変更<=することで簡単に修正できます。<for


配列のサイズが 10 から 11 に変更されたときに問題が解決する理由は、問題を引き起こしているループの上のループarraysizeで 10 までインクリメントされることに関係しています。for配列内のインデックスの範囲が現在 であるため、今回singles[10]は が配列内の有効な要素です[0, 11)

編集:実際arraysizeには 11 にインクリメントされる可能性があります。0 に初期化されていると思っていましたが、その場合は 10 にしかなりません。いずれにしても、上記はまだ有効です。配列はゼロから始まるため、取得している例外を回避するために、配列内で試行してアクセスする最後のインデックスは、配列の長さよりも 1 小さい必要があります。ええ、要するに、そうある<=べきです<

于 2011-12-01T03:08:25.767 に答える
0

私は本当に眠っているはずなので、20のように編集します。私はおそらくあなたのために宿題をしただけだと気づいたので、コードを削除しました.

arraySize は 0 から開始する必要があります。これは、数値なしで開始し、重複を見つけたときにこのサイズを追加し始めるためです。10 回繰り返される数値が 1 つだけであると仮定すると、サイズ 2 の配列を作成して 1 つの数値を格納することになります。int arraysize = 0;

最初の for ループは をループする必要がnumbersあるため、ループ制約で数値の長さを使用することは理にかなっています。for( int i = 0; i < numbers.length; i ++)

tracker2 番目の for ループの場合:配列全体をトラバースする必要があるため、その長さを使用することもできます ( tracker.length)。マジック ナンバーが少ないことは常に良いことです。singles配列内の位置を追跡するために、別の変数も必要です。数字が 10 個の 9 の配列である場合、tracker[9] のみが true になりますが、これは singles[0] に配置する必要があります。繰り返しますが、私の説明は下手ですが、図がないと難しいです。

Derp derp、私は気分がいい/寝る気がするので、出来上がり、私が使用したコード(テストしようとしたときに機能しました):

public static int[] eliminateduplicates(int[] numbers)
{
    boolean[] tracker = new boolean[10];
    int arraysize = 0; 

    for(int k = 0; k < numbers.length; k++)
    {
        if(tracker[numbers[k]] == false)
        {
            arraysize++;
            tracker[numbers[k]] = true;
        }
    }

    int[] singles = new int[arraysize];

    for(int l = 0, count = 0; l < tracker.length; l++)
    {
        if(tracker[l] == true)
        {
            singles[count++] = l;
        }
    }

    return singles;
}
于 2011-12-01T03:08:58.537 に答える