2012-01-10 7 views
1

問題は次のとおりです。可能なすべての行の組み合わせをテストしてください

id value 
0: {1,2,3} 
0: {1,2,2} 

1: {1,2,3} 

2: {1,2,3} 
2: {1,1,3} 

私は互いの間に複数の行を比較することができます機能equalsを持っている:非一意の識別子を持つ複数の行があります。関数equalsの入力として行を選択するコードを書く必要があります。選択された行には一意のIDが必要ですが、一意のIDのすべての可能な組み合わせをチェックする必要があります。たとえば、ids:0,0,1,2,3の5つの行がある場合、0,1,2,3と0,1,2,3の次の2つの組み合わせをチェックする必要があります。0二度出現する。もちろん、これら2つの組み合わせのそれぞれは、id = 0の一意の行で構成されます。

私のコードスニペットは以下の通りです:

public class Test { 
public static void main(String[] args) { 
    ArrayList<Row> allRows = new ArrayList<Row>(); 
    allRows.add(new Row(0,new int[]{1,2,3})); 
    allRows.add(new Row(0,new int[]{1,2,2})); 
    allRows.add(new Row(1,new int[]{1,2,3})); 
    allRows.add(new Row(2,new int[]{1,2,3})); 
    allRows.add(new Row(2,new int[]{1,1,3})); 

    boolean answer = hasEqualUniqueRows(allRows); 
} 

private boolean hasEqualUniqueRows(ArrayList<Row> allTokens) { 
    for (int i=0; i<allTokens.size(); i++) { 
     ArrayList<Integer[]> rows = new ArrayList<Integer[]>(); 
     rows = findUniqueRows(i,allTokens); 
     boolean answer = equalsExceptForNulls(rows); 
     if (answer) return true; 
    } 
    return false; 
} 
// Compare rows for similarities 
public static <T> boolean equalsExceptForNulls(ArrayList<T[]> ts) { 
    for (int i=0; i<ts.size(); i++) { 
     for (int j=0; j<ts.size(); j++) { 
      if (i != j) { 
       boolean answer = equals(ts.get(i),ts.get(j)); 
       if (!answer) return false; 
      } 
     } 
    } 
    return true; 
} 

public static <T> boolean equals(T[] ts1, T[] ts2) { 
    if (ts1.length != ts2.length) return false; 
    for(int i = 0; i < ts1.length; i++) { 
     T t1 = ts1[i], t2 = ts2[i]; 
     if (t1 != null && t2 != null && !t1.equals(t2)) 
      return false; 
    } 
    return true; 
} 

class Row { 
      private String key; 
      private Integer[] values; 

     public Row(String k,Integer[] v) { 
      this.key = k; 
      this.values = v; 
     } 

     public String getKey() { 
      return this.key; 
     } 

     public Integer[] getValues() { 
      return this.values; 
     } 
} 

}

ユニークなIDを持つ行数は不明先験的なので、私はドントこの問題を解決する方法を知っています。助言がありますか?ありがとう。

編集#1 コードを更新しました。今はより完全です。しかし、それは機能findUniqueRowsの実装が欠けています。この関数は、一意のキー(ids)を持つ行をArrayListから選択する必要があります。誰かが私にこの機能の開発を手伝ってもらえますか?ありがとう。

+0

*「何か提案がありますか?」*より早い時期に役立つようにするには、[SSCCE](http://sscce.org/)を投稿してください。ところで、この宿題は? –

+0

いいえ、それは宿題ではありません。 SSCCEを掲示する際の問題は、現在のバージョンの関数 'equals'が入力として3行で動作することです。したがって、私はここに投稿することはできません。私は、行の組み合わせを段階的に選択するコードスニペットや提案を待っています。誰かが概念的な解決策を提供できるのでしょうか? –

+0

私はユニークな組み合わせを生成するだけの戦略を使用します。これにより、重複を見つけて削除する必要がなくなります。 –

答えて

1

目的が重複なしですべての組み合わせを見つけることであると仮定すると、次のようにこれを行うことができます。重複を見つけるテストは、重複が最初に発生しないことを確認することです。

import java.util.*; 
import java.util.concurrent.atomic.AtomicInteger; 

public class Main { 
    public static void main(String... args) { 
     Bag<Integer> b = new Bag<>(); 
     b.countFor(1, 2); 
     b.countFor(2, 1); 
     b.countFor(3, 3); 
     Set<String> set = new LinkedHashSet<>(); 
     for (List<Integer> list : b.combinations()) { 
      System.out.println(list); 
      String s = list.toString(); 
      if (!set.add(s)) 
       System.err.println("Duplicate entry " + s); 
     } 
    } 
} 

class Bag<E> { 
    final Map<E, AtomicInteger> countMap = new LinkedHashMap<>(); 

    void countFor(E e, int n) { 
     countMap.put(e, new AtomicInteger(n)); 
    } 

    void decrement(E e) { 
     AtomicInteger ai = countMap.get(e); 
     if (ai.decrementAndGet() < 1) 
      countMap.remove(e); 
    } 

    void increment(E e) { 
     AtomicInteger ai = countMap.get(e); 
     if (ai == null) 
      countMap.put(e, new AtomicInteger(1)); 
     else 
      ai.incrementAndGet(); 
    } 

    List<List<E>> combinations() { 
     List<List<E>> ret = new ArrayList<>(); 
     List<E> current = new ArrayList<>(); 
     combinations0(ret, current); 
     return ret; 
    } 

    private void combinations0(List<List<E>> ret, List<E> current) { 
     if (countMap.isEmpty()) { 
      ret.add(new ArrayList<E>(current)); 
      return; 
     } 
     int position = current.size(); 
     current.add(null); 
     List<E> es = new ArrayList<>(countMap.keySet()); 
     if (es.get(0) instanceof Comparable) 
      Collections.sort((List) es); 
     for (E e : es) { 
      current.set(position, e); 
      decrement(e); 
      combinations0(ret, current); 
      increment(e); 
     } 
     current.remove(position); 
    } 
} 
関連する問題