このプログラムはどこから入手できますか?また、なぜこれが1つの配列サイズを増やすことによって引き起こされるのですか? (Java)

StackOverflow https://stackoverflow.com/questions/8335998

質問

このプログラムは、単に配列から複製を排除することになっています。ただし、Eliminateメソッドのループの2番目は、範囲外の例外を投げることでした。私は見ていて、それがどのようになるかを見ることができなかったので、アレイのサイズを1だけ増やすので、唯一の欠点が端に留められているだけで動作させることができました。

驚いたことに、トラッカー[]のサイズを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,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;
}
役に立ちましたか?

解決

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

Arraysizeは0から始まる必要があります。これは、数値なしで開始し、複製を見つけるとこのサイズに追加し始めるためです。 10回繰り返された数が1つしかないと仮定すると、1つの番号を保存するためにサイズ2の配列を作成したでしょう。 int arraysize = 0;

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

ループの2番目の場合:あなたは全体を横断する必要があります tracker 配列なので、そのために長さを使用することもできます(tracker.length)。魔法の数が少ないことは常に良いことです。また、あなたの場所を追跡するために別の変数が必要です singles 配列。数字が10 9の配列である場合、トラッカー[9]のみが真実ですが、これはシングル[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;
}

他のヒント

配列は0から始まるため、配列は一意の数字の数よりも大きくなるため、最終ループは何度も経過します。言い換えれば、「L」(文字L-別の変数名を使用してみてください)は、10個の一意の数字があり、トラッカーにはアイテム0〜10のみがある場合は11になります。宣言をint arraysize = 0に変更してみてください。

再び<=によって敗北しました

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

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

数字がどこから来ているのか

singles[l] = l;

カウント値をシングルフィールドに割り当てるので、シングル[1]には1などが割り当てられています。

私はあなたが複製を取得するためにあまりにも多くの処理をしていると感じています、あなたがコレクションを使用しないという制限がない場合、あなたはこれを試すことができます

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つのインデックスに進みます。

Javaの配列内の有効なインデックスの範囲は [0, SIZE), 、すなわち。 0から arraysize-1.

あなたが例外を取得している理由は、あなたのループであなたが0から繰り返しているからです arraysize 包括的に, 、1つのインデックスが遠すぎます:

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

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


アレイのサイズが10から11に変更されたときに問題がなくなる理由は関係があります arraysize で最大10まで増加しています for 問題を引き起こす1つの上にループします。今回、 singles[10] アレイのインデックスの範囲は今ではあるので、配列の有効な要素です [0, 11).

編集: 実際 arraysize 11に増分する可能性があります。私はそれが0に初期化されたと思いました。その場合、10にしか到達しません。配列でアクセスしようとする最後のインデックスは、アレイがゼロベースであるため、取得する例外を回避するために、配列の長さより1少ない必要があります。ええ、短い話、 <= あるべきです <.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top