0

配列内で重複する値を検索し、それが 2 回発生したときに true を返すメソッドを作成しようとしています (それ以外の場合は false を返します)。

私は何かを持っていますが、何らかの理由で、特定のケースでは正しく動作しません:

public static boolean twoDuplicates(int[] values) {

    boolean twoDuplicate = false;
    int counter = 0;

    for(int i = 0; i < values.length; i++){
        for(int z = i + 1; z <= values.length - 1; z++){
            if(i != z && values[i] == values[z])
                counter++;
        }
    }
    if(counter == 2)
        twoDuplicate = true;
    return twoDuplicate;
}

今、テストしましたが、値が [3,3,3,6,6] の場合は機能しません。理由はありますか?

編集:重複は区別する必要があることを忘れていました。

4

6 に答える 6

1

一致の総数を数えているだけのようです。つまり、3 を 2 回 (今はカウンター = 3)、z を 1 回、合計 4 に一致させることになります。このコードを配列で実行すると、counter = 4; が得られます。

次のコードは、個別の重複の数を返すと思います(重複が何回発生しても、重複のある数)。これは、テスト配列に対して 2 を返します。最初に配列をソートし、次に重複を見つけ、すでにカウントされている重複を無視します。

public static boolean twoDuplicates(int[] values) {

        boolean twoDuplicate = false;
        int counter = 0;
        Arrays.sort(values);
        int old = values[0];
        boolean numberSeen = false;
        for(int i = 0; i < values.length; i++){
            if(values[i] == old){
                if(!numberSeen){
                    counter++;
                    numberSeen = true;
                }
            }else{
                numberSeen = false;
                old = values[i];
            }
        }
        if(counter == 2)
            twoDuplicate = true;
        return twoDuplicate;
    }
于 2013-04-15T02:49:26.527 に答える
0

状況はそのようなものです:

最初のループは最初の 3 を読み取ります。2 番目のループは 2 番目と 3 番目の 3 を読み取ります。カウンターは 2 になります。最初のループは 2 番目の 3 を読み取ります。2 番目のループは 3 番目の 3 を読み取ります。カウンターは 3 になります。最初のループは 3 番目の 3 を読み取ります。2 番目のループは何も見つかりません。カウンターは 3 です。最初のループは最初に 6 を読み取ります。2 番目のループは 2 番目の 6 を読み取ります。カウンターは 4 です。最初のループは 2 番目の 6 を読み取ります。2 番目のループは何も見つかりません。カウンターは4。

あなたがする必要があるのは、それif( counter == 2 )を2番目のループの後に置くことです。これで問題は解決します。

if( counter == 2 ) return true;

于 2013-04-15T02:53:29.083 に答える
0

1. 最初に見つかった重複ペアの値を覚えておく必要があります。

それ以外の場合は、3,3,3 と続けて - 3 が 2 回見つかります。したがって、最初の重複値を保存して比較すると、これはそうではありません。

int firstDuplicate;


if(i != z && values[i] == values[z]) {

     if (counter == 0) {

          counter++;
          firstDuplicate = values[i];

     } else if (counter == 1 && values[i] != firstDuplicate) {

          counter++;
     }
}

2. z <= values.length - 1する必要がありますz < values.length。最初に使用したようにfor

3. { }ブロックが単線であっても常に使用します。

UPD

4 . break;必要なものが見つかったときに反復を停止するために使用します。

for(){
    for(){

    }
    if(counter == 2) {
        twoDuplicate = true;
        break;
    }
}

またはそれ以上

for(int i = 0; i < values.length && counter < 2; i++;){
    for(){

    }
}

return counter >= 2;
于 2013-04-15T02:54:59.877 に答える
0

あなたの論理によれば、2 つ以上の重複がある場合、関数は false を返します。おそらく、「counter>1」を使用して判断し、カウンター定義を外側の反復に配置する必要があります。そして、アルゴリズムが十分に賢くないと思います。

于 2013-04-15T02:48:14.013 に答える
0

これは、1つのループだけで行う方法です

    public static boolean twoDuplicates(int[] values) {
    HashSet<Integer> map = new HashSet<Integer>();
    int cont = 0;
    for (int i = 0; i < values.length; i++) {
        if (map.contains(values[i])){
            cont++;
            if (cont == 2) 
                return true;
        }           
        else
            map.add(values[i]);

    }
    return false;
}
于 2013-04-15T03:13:37.177 に答える