0

これを解決したいのですが、方法がわかりません...

Values[10] = {1,1,4,4,2,3,3,2,1,3}

印刷する:

{1,2,3,4} or {1,4,2,3} (not sorted, any order, but distinct)

また、ソート、新しい配列、ブールメソッド、またはその他のデータ構造の両方を使用せずに、各数値が発生した回数をカウントする必要があります。行き詰まっているのでアドバイスしてください。

一意の値/個別の値を印刷するために使用できる簡単な方法はありますか?

4

4 に答える 4

1

追加のオブジェクトを作成しない別の解決策:

Arrays.sort(values);
for(int i = 0; i < values.length; i++) {
    if (i == 0 || value[i] != value[i-1]) {
        System.out.println(values[i]);
    }
}

そして、私が考えることができる最短の解決策:

Integer[] values = {1,1,4,4,2,3,3,2,1,3};
Set<Integer> set = new HashSet<Integer>();
set.addAll(Arrays.asList(values));
System.out.println(set); 
于 2012-08-10T17:22:24.160 に答える
1

値が整数であることが保証されていると仮定すると、チェック値をインクリメントし、配列をスキャンし、配列内のそのチェック値の数を合計し、それをアキュムレータに追加して、accumulator < array.length の間ループすることによっても実行できます。 .

このようなもの(テストされていません):

public void checkArray(int[] toCheck) {
    int currentNum = 0;
    int currentCount = 0;
    int totalSeen = 0;

    StringBuilder sb = new StringBuilder();

    int min = Integer.MAX_VALUE;
    int max = Integer.MIN_VALUE;
    for(int i=0; i<toCheck.length; i++) {
        min = Math.min(toCheck[i], min);
        max = Math.max(toCheck[i], max);
    }

    System.out.print("{ ");
    for(currentNum = min; currentNum < max; currentNum++) {
        for(int i=0; i<toCheck.length; i++) {
            if(toCheck[i] == currentNum) currentCount++;
        } 

        if(currentCount != 0) {
            if(currentNum == min) System.out.print(currentCount + "(" +currentCount+ ")");
            else System.out.print(", " + currentCount + " (" +currentCount+ ")");
        }
        totalSeen += currentCount;
        currentCount = 0;
    }
    System.out.println(" }");
}

これは技術的にはすべての要件を満たしていますが、gbtimmon のアプローチよりもはるかに効率が悪いことに注意してください。

たとえば、int がの場合{1,2,3,150000}、4 から 149999 までのすべての値を不必要にスピンオーバーします。

編集:tbitofの提案からより良い制限を追加しました。

于 2012-08-10T18:08:56.837 に答える
1

現在のアレイを破棄しても構わないと思っている場合は、これを行うことができます。そして、配列は Integer 型 (null 可能) であるか、そうでない場合はすべての int などの境界が正であるため、 を使用できると想定します-1

for(int i = 0;  i < values.length; i++){               //for entire array             

    Integer currVal = values[i];                       // select current value
    int count = 1;                                     // and set count to 1

    if(currVal != null){                               // if value not seen

        for( int j = i + 1; j < values.length; j++){   // for rest of array
            if(values[j] == currVal){                  // if same as current Value 
                values[j] = null;                      // mark as seen
                count++;                               // and count it 
            } 
        }
        System.out.print("Number : "  + currVal + "  Count : " + count + "\n");
                                                       //print information
    }
                                                       // if seen skip.
}

簡単に言えば、配列を 2 つのループで処理します。およそ O(n^2) 時間です。インデックス i に移動します。インデックスがまだ表示されていない (null でない) 場合は、配列の残りの部分を調べて、表示されているものと同じ値を持つインデックスをマークし (null にします)、count 変数をインクリメントします。ループの最後に、値とカウントを出力します。インデックスが表示された場合 (null の場合) スキップして次のインデックスに移動します。両方のループの最後で、すべての値は null のままになります。

Input : Values[] = {1,1,4,4,2,3,3,2,1,3}


Output : Values[] = {1,null,4,null,2,3,null,null,null,null}
          Number : 1 Count : 3
          Number : 4 Count : 2
          Number : 2 Count : 2
          Number : 3 Count : 3

編集:コメント者から指摘された出力の間違いを修正しました。

于 2012-08-10T17:29:57.197 に答える
0

追加のオブジェクトをまったく作成せずにこれらのことをしたいように聞こえるので、あなたの質問は私にはよくわかりません。ただし、別の配列を作成しないだけの場合は、を使用できますMap<Integer, Integer>。ここで、キーは元の配列の番号であり、値はそれを見た回数です。最後に、すべての数字のカウントを調べ、すべてのキーを出力することができます。Map.keyset()

編集:例:

Map<Integer,Integer> counts = new HashMap<Integer, Integer>();
for( int i : values ) {
    if( counts.containsKey(i) ) {
        counts.put(i, counts.get(i) + 1);
    } else {
        counts.put(i, 1);
    }
}

// get the set of unique keys
Set uniqueInts = counts.keyset();
于 2012-08-10T17:18:00.030 に答える