4

同じ数の数値を含む2つのint配列のセットがあります

例えば

int[] array1 = {1,3,5,5,2}
int[] array2 = {5,3,4,4,4}

2つの基準に基づいてそれらを比較する必要があります

  1. 同じインデックスで同じ値を持つ要素の数
  2. 異なるインデックスで同じ値を持つ要素の数

そして、値を表す整数の配列を返します

あなたがよりよく理解できるように、私はいくつかの例を持っています:

   int[] array0 = {1,3,5,5,2};
   int[] array1 = {5,3,4,4,4};
   int[] array2 = {5,3,4,4,5};
   int[] array3 = {2,3,2,2,4};
   int[] array4 = {5,5,2,1,3};
   int[] array5 = {3,1,5,5,2};
   int[] array6 = {1,3,5,5,2};

   compare(array0,array1); //this would return 1,1
   compare(array0,array2); //this would return 1,2
   compare(array0,array3); //this would return 1,1
   compare(array0,array4); //this would return 0,5
   compare(array0,array5); //this would return 3,2
   compare(array0,array6); //this would return 5,0

最初の数字は簡単です。array1のインデックスiの要素がarray2の要素と同じかどうかを確認する必要があります。

配列の1つから最小の数を取得する必要があるため、2番目の数を生成するのに問題があります。array1の要素がarray2のどこかにあるかどうかを調べると、場合によっては間違った結果が生成されます。

あなたが見れば

int[] array1 = {1,3,5,5,2}

int[] array3 = {2,3,2,2,4};

そして、array1がインデックスのarray3と同じ内容を持っているかどうかを確認すると、3つの数値は等しいが、異なる場所に返されます。これは、最小の数値から判断し、結果が1になるため、間違っています。

あるインデックスでarray3がarray1と同じ内容であるかどうかを比較するために切り替えると、この場合は機能しますが、他の場合は機能しません。

これにアプローチする方法についてのアイデアはありますか、私はかなり無知ですか?

4

7 に答える 7

1
  • 2つの入力整数配列のクローンを作成します。

  • 要素が同じインデックスで同じ値を持っているかどうかを確認してください。

  • その場合は、同じインデックスカウンターに1を加算し、入力整数配列の値を-1(または有効な最小値よりも小さい数値)に変更します。

  • ネストされたforループを使用して、要素が同じ値を持っているかどうかを確認します。つまり、最初の整数配列の最初の要素と2番目の整数配列のすべての要素をチェックします。両方の配列で同じインデックスを持つ要素をスキップし、最小の有効な値よりも小さい要素をスキップします。

  • その場合は、別のインデックスカウンターに1を加算し、入力整数配列の値を-1(または有効な最小値よりも小さい数値)に変更します。

于 2012-11-07T19:39:31.453 に答える
0

おそらく2番目の条件では、配列から数値を削除し、一致することがわかったらループから抜け出してみることができます。元の配列の値に設定した一時配列を持つことができます。次に、の値をarray1[0]のすべての値と照合しますarray3。一致するものが見つかったら、両方の配列から番号を削除し、のarray1[1]すべての値と照合しますarray3

array1[4]したがって、に対してチェックするとarray3[0]、一致するものが得られます。次に、両方の番号を削除して、ループから抜け出します。チェックインする番号がこれ以上ないarray1ため、結果は1になります。

これにより、同じ値を2回カウントする問題が解決されると思います。

于 2012-11-07T19:39:59.190 に答える
0

あなたはすでに訪問された番号を持つセットを持つことができます。あなたは次のようになります:(このコードが実行されるかどうかをテストするのではなく、単にアイデアを与えるためです)

public int[] compare(int[] first, int[] second) {
     Set<Integer> numbersFoundInFirstArray = new LinkedHashSet<Integer>();
     Set<Integer> numbersFoundInSecondArray = new LinkedHashSet<Integer>();
     int inSameIndex = 0;
     int inDifferentIndex = 0;

     for (int i; i < first.length; i++) {
         if (first[i] == second[i]) {
             inSameIndex++;
         }
         if (numbersFoundInFirstArray.contains(second[i])) {
             inDifferentIndex++;
         }
         if (numbersFoundInSecondArray.contains(first[i])) {
             inDifferentIndex++;
         }
         numbersFoundInFirstArray.add(first[i]);
         numbersFoundInSecondArray.add(second[i]);
     }
     return new int[] {inSameIndex, inDifferentIndex};
}

よく覚えていれば、セット内の包含比較にはO(1)があります。Setのプロパティは、特定のタイプの要素を1つだけ持つことです。したがって、1を2回追加すると、1の参照は1つだけになります。このように、現在の番号が他の配列ですでに見つかっているかどうかのみをテストします:)

于 2012-11-07T19:43:18.863 に答える
0

すべての配列をツリーのような構造に転置する必要があります。これにより、基本的にすべての配列のすべての一意の値にインデックスが付けられ、配列内のそれらの位置とどの配列へのポインターが格納されます。そのツリーの基本的な青写真の構造は次のようになります。

uniqElemVal->arrayIndx->arrayID = true

uniqElemValが1,3,5,5,2の場合は1,3,5,2、2,3,2,2,4の場合は2,3,4など、すべてユニオン化されます

arrayIndxは、最初の配列0の1になり、5は2と3になります。

配列IDは任意のものであり、各配列にキーを設定できます。たとえば、最初の配列に1、2番目の配列に2などです。

したがって、この場合:

#1st array
1->0->1
3->1->1
5->2->1
5->3->1
2->4->1

#2nd array
2->0->2    
3->1->2 
3->2->2
2->3->2
2->4->2
4->5->2

次に、このツリーをトラバースすると、リーフが1つを超える第2レベルのノードがある場合は常に、複数の配列の特定の位置にある特定の要素の値が一致することを意味します。

私は個人的にこの木を次のように定義します

HashMap<Integer, HashMap<Integer, ArrayList<Integer>>>

したがって、要素が1を超えるリーフ配列リストがある場合は常に、一致するものがあることを意味します。

于 2012-11-07T19:46:21.453 に答える
0

まず第一に、これは本当に悪い考えのように聞こえます。各インデックスが異なる不可解なものを意味する配列を返さないでください。2つのメソッドを作成します:compareSameIndex(array、array)とcompareDifferentIndex(array、array)。

これらの方法を実際に実装するには、最初の配列のすべてのインデックスをチェックして、それらが2番目の配列のどこかに表示されるかどうかを確認し、compare()を呼び出すことができます。次に、compareDifferentIndex()はcompare()-compareSameIndex()になります。例えば:

public int compare (int[] array0, int[] array1) {
  int matches = 0;
  List<Integer> list1 = Arrays.asList(array1);

  for (int curInt : array0) {
    if (list1.contains(curInt)) {
      matches++;
    }
  }
  return matches;
}

public int compareSameIndex(int[] array0, int[] array1) {
  int matches = 0;
  for (int i=0; i < array0.length; i++) {
    if (array0[i] == array1[i]) {
      matches++
    }
  }
  return matches;
}

public int compareDifferentIndex(int[] array0, int[] array1) {
  return compare(array0, array1) - compareSameIndex(array0, array1);
}

同じ番号が2回表示された場合に何が起こるかについての要件は少し曖昧に見えますが、それに対応するためにそのロジックをcompare()に組み込むことができます。また、同じ数を2回チェックしない非常に大きな配列に対してこれを最適化することもできますが、これは私が採用する一般的なアプローチです。

于 2012-11-07T19:48:00.340 に答える
0

引数をチェックすることは良い習慣です。ここで実行できるいくつかのマイナーな最適化がおそらくありますが、ハッシュを使用すると、すでにアクセスした位置を保存して、それらを2回以上カウントしないようにすることができます。

 private int[] compare(int[] arr1, int[] arr2){
    int same_index = 0;
    Hashtable differences = new Hashtable();
    int diff_count = 0;
    if (arr1.length != arr2.length){
        throw new IllegalArgumentException("Array Size is not identical.");
    } else {
       for(int count = 0; count < arr1.length; count++){
          if (arr1[count] == arr2[count]{
              same_index++;
              differences.put(count, null);
          } else {
              for (int count2 = 0; count2 < arr1.length; count2++){
                  if(!differences.containsKey(count2) && arr1[count] == arr2[count2]){
                      differences.put(count2, null);
                      diff_count++;
                  }

              }                  
          }
       }
    }
    int[] returnArray = new int[2];
    returnArray[0] = same_count;
    returnArray[1] = diff_count;
    return (returnArray);
 }
于 2012-11-07T19:52:33.043 に答える
0

これでうまくいくはずです:

public void compare(int[] arrayA, int[] arrayB) {
    int sameIndex = 0;
    int diffIndex = 0;
    //Made two new empty arrays to save the status of each element in the corresponding array, whether it has been checked our not, if not, it'd be null.
    String[] arrayAstatus = new String[arrayA.length];
    String[] arrayBstatus = new String[arrayB.length];
    for (int i = 0; i < arrayA.length; i++) {            
        if (arrayA[i] == arrayB[i] || arrayAstatus[i] != null) {
            sameIndex++;
            continue;
        }
        for (int a = 0; a < arrayB.length; a++) {
            if (a == i || arrayBstatus[a] != null) {
                continue;
            }
            if (arrayA[i] == arrayB[a]) {
                arrayAstatus[i] = "checked";
                arrayBstatus[a] = "checked";
                diffIndex++;
                break;
            }
        }
    }
    System.out.println(sameIndex + ", " + diffIndex);
}
于 2012-11-07T20:40:45.183 に答える