2011-12-23 15 views
2

私はこれをできるだけ簡単に置いているプログラムを作成しようとしています - 私は三角形の辺を見つけました。オブジェクトが作成されているかどうかを確認してください

これを行う際の問題は、まったく同じ面で見つかった別の三角形がある可能性があることです。たとえば、

1, 2, 1の三角形と1, 1, 2の三角形が見つかった場合、私がやっていることの規則のために、この三角形を再度使用する必要はありません。別の順序で。

= new triangle(x,y,z)のような三角形の値を入力できるクラスを作成します。ここで、x、y、zはすべて辺の整数です。

私は既にクラスを持っているので、これは問題ではありません。問題は、三角形がすでに入力したのと同じ面で作られているかどうかを確認する方法です。

ありがとうございました。

+0

同様の辺を持つ2つの三角形をマージして、何を達成しようとしていますか? Stringインターンのようなヒープ上に余分なオブジェクトを割り当てるのを防ぐのですか?またはある種の計算(領域)でパフォーマンスのためにルックアップキャッシュを使用しようとしていますか? – wrschneider

+1

1.辺「1,2,1」を持つ三角形を持つことは不可能です。 a + b> c、b + c> a、a + c> bである。 2.「三角形の辺を見つける」ことについてもっと詳しく説明する必要があります。何に基づいて? – khachik

+1

私は三角形の辺を見つけるのに助けは必要ありません。それが私がそれについて詳しく述べなかった理由です。 – nmagerko

答えて

2

オーバーライドequalsTrianglehashCode「同じ」の三角形を検出し、これまでに作成されたすべてのTriangleHashSet<Triangle>を維持します。あなたが重複せずに三角形を印刷したい場合は、あなたが行うことができます。例えば

、:

Set<Triangle> triangles = new HashSet<Triangle>(); 
for (String line : file) { 
    Triangle t = makeTriangle(line); 
    triangles.add(t); // does nothing if an equal Triangle is already in the set 
} 
System.out.println("The distinct triangles are:"); 
for (Triangle t : triangles) { 
    System.out.println(t); 
} 

class Triangle { 
    private int[] sides; 

    public Triangle(int x, int y, int z) { 
     sides = new int[] {x,y,z}; 
     Arrays.sort(sides); 
    } 

    @Override public boolean equals(Object o) { 
     return o instanceof Triangle && Arrays.equals(sides, ((Triangle) o).sides); 
    } 

    @Override public int hashCode() { 
     return Arrays.hashCode(sides); 
    } 

    @Override public String toString() { 
     return Arrays.toString(sides); 
    } 
} 

注:このアプローチは、あなたがいるかどうかを確認するために、新たなトライアングルを作成する必要がありますそれは複製です。オブジェクトの割り当てを回避するアプローチを拡張することができますが、パフォーマンスの向上がほとんどないためにコードが複雑になります。

+0

2つの質問:1)三角形を作成し、それが「コピー」である場合、それは自動的に削除されますか? 2)名前を付けずに新しい三角形を作成するにはどうすればよいですか?私は三角形を見つけるためにループを使用しているので、どうすれば別の名前でそれらを追加できますか? – nmagerko

+0

1)それはあなたがHashSetとやり取りする方法に依存しますが、私は例を追加しました。 2)三角形の名前を付ける場合は、名前を格納するためにTriangleクラスに新しいフィールドを作成します。 – meriton

+0

完璧!私は立ち往生するかどうかを知らせますが、これは素晴らしいことです。 – nmagerko

2

これを行う1つの方法は、すべてをSetに入れ、エッジ/サイドの順序が重要でないようにequals()hashCode()メソッドを実装することです。そうすれば、Triangle(1,2,1)またはTriangle(1,1,2)を与えると、equalsメソッドとhashCodeメソッドはどちらも同じ値を返します。

0

equals(Object o)hashcodeのメソッド(http://www.javapractices.com/topic/TopicAction.do?Id=17を参照)を実装するときは、Triangleクラスの辺の長さを使用します。次に、すでに存在するセットを作成します。新しい三角形がある場合は、そのセットに既に含まれているかどうかを確認します。

Set<Triangle> existingTriangles = new HashSet<Triangle>(); 
// loop 
Triangle newTriangle = new Triangle(side1, side2, side3); 
// Already exists 
if (existingTriangles.contains(newTriangle)) { 

} 
// New triangle 
else { 

} 
+0

いつでも新しいTriangleインスタンスを作成する –

+0

私はこれを試してみたいと思います! – nmagerko

+0

@ narek.gevorgyan真。アプリケーションによっては問題ないかもしれません。 – I82Much

2

1)Triangleクラスでequalsが正しく実装されていることを確認してください。

2)次に、三角形オブジェクトの静的コレクションを作成し、そのコレクションを三角形クラスに格納します。

class Triangle 
{ 
static Set<Triangle> cache = new TreeSet<Triangle>(); 
... 

は、次に三角形のコンストラクタをプライベートにして三角形を作るための工場を使用し、三角形が作成されるので、すべての時間には、同一の三角形がこのコレクション内に存在しないことを確認してください。

3)ここで、三角形を作成するためのファクトリメソッドを追加します。

public static Triangle createTriangle(int x , int y, int z) 
{ 
    Triangle t = new Triangle(x,y,z)); 
    if(! cache.contains(t)) 
     cache.put(t); 

    return cache.get(t);  
} 

静的なコレクションは、作成されたすべての三角形へのポインタで保持されます。

+0

私はこれをupvotedしたいと思いますが、あるコードスニペット( 'createTriangle')には4つのコンパイルエラーがあります。 – meriton

+0

また、インターフェイス( 'static Set キャッシュ...')にコードを書くことをお勧めします。 –

+0

は、恐ろしいエラーをいくつか修正しました – jayunit100

0

先ほど作成した三角形のキャッシュ(可能な場合はSet)を保存する必要があります。 Triangleメソッドが正しく.hashCode().equals(Object)をオーバーライドする場合は、作成したセットに対して.contains(Object)メソッドを使用して、それが既に存在するかどうかを確認することができます。

Triangle t = new Triangle(x, y, z); 

if (!cache.contains(t)) 
{ 
    cache.add(t); 

    // do something with new object 
} 
else 
{ 
    Triangle cachedTriangle = cache.get(t); 

    // do something with cached object 
} 
0

あなたの場合、あなたのオブジェクトのうちの2つのオブジェクトが等しくて、それぞれの一辺の長さが他のものと同じであると定義します。これを解決する1つの方法は、オーバーライドequals()メソッドです。 (その場合には、同様hashCode()を上書きすることを忘れないでください。)次に、あなたが対等の動作を変更するために好きではない場合は、ちょうどクラスに独自のメソッドを定義

if (triangle1.equals(triangle2)) {...} 

を行うことができます、例えばcompare(anotherTrinangle)を入力し、同じロジックを入力します。

すべての三角形は、希望の種類のCollectionに保存することができます。

0

それがトライアングルクラスでは、まだ存在しない、または他のちょうど作成しない場合、私は考えることができる最も簡単な方法は、静的メンバを使用している、を言うならば、あなたはcreateTriangle()に場所にロジックを持っている場合。

三角形を作成するたびに、それを増やします。実際に作成されたかどうかを確認する場合は、こののカウントの値を現在の値と比較してください。

0

ええと、どうして違うの?他のすべてのアプローチでは、類似するものが既に存在するかどうかを本当に知りたい場合は常に、Triangleオブジェクトを作成します。確かに、GCはそのオブジェクトの世話をします...
ここは私の考えです。
まず、このようにテストを書く:

@Test 
public void testSimple() { 
    final Triangle t1 = Triangle.create(1, 2, 3); 
    final Triangle t2 = Triangle.create(1, 3, 2); 

    assertNotNull(t1); 
    assertSame(t1, t2); 
} 

は、単一の属性の長さと横のようなクラスを持っています。 equals()とhashCode()の実装は非常に簡単です。次に、長さ引数を順序付け/正規化し、一貫性のある方法でそれらを置く/取得する/チェックします。

static Map<Side, Map<Side, Map<Side, Triangle>>> triangles = new HashMap<Side, Map<Side, Map<Side, Triangle>>>(); 

public Triangle(final int x, final int y, final int z) { 
// ... 
} 

public static Triangle create(final int x, final int y, final int z) { 
    final Side min = new Side(Math.min(Math.min(x, y), z)); 
    final Side middle = new Side(Math.min(Math.max(x, y), z)); 
    final Side max = new Side(Math.max(Math.max(x, y), z)); 

    final Map<Side, Map<Side, Triangle>> middleMap; 
    final Map<Side, Triangle> maxMap; 
    if (triangles.containsKey(min)) { 
     middleMap = triangles.get(min); 
    } 
    else { 
     middleMap = new HashMap<Side, Map<Side, Triangle>>(); 
     triangles.put(min, middleMap); 
    } 
    if (middleMap.containsKey(middle)) { 
     maxMap = middleMap.get(middle); 
    } 
    else { 
     final Triangle triangle = new Triangle(x, y, z); 
     maxMap = new HashMap<Side, Triangle>(); 
     maxMap.put(max, triangle); 
     middleMap.put(middle, maxMap); 
     return triangle; 
    } 
    if (maxMap.containsKey(max)) { 
     return maxMap.get(max); 
    } 
    final Triangle triangle = new Triangle(x, y, z); 
    maxMap.put(max, triangle); 
    return triangle; 
} 
-1

私はあなたのother postを読んで、あなたが新しいJavaの開発者であるので、私は実行している例を与える必要性を見つけ印象を受けました。 これをIDEにコピーして実行するだけです。それは実行し、あなたのための概念の証明である出力を生成する必要があります。

私はここに使用していた入力は

String[] input = new String[]{ "1,2,1" , 
           "1,1,2", 
           "1,2,3", 
           "1,3,1", 
           "1,1,1", 
           "1,3,3", 
           "1,1,3"}; 

そして、あなたはそれはあなたが説明するように繰り返しを持って見ることができるようです。あなたは出力が無いの繰り返しであり、要求通り 出力は

The triangle [Triangle{sides=[1, 1, 2]}] already exists! 
The triangle [Triangle{sides=[1, 1, 3]}] already exists! 
triangles = [Triangle{sides=[1, 2, 3]}, 
       Triangle{sides=[1, 1, 3]}, 
       Triangle{sides=[1, 1, 2]}, 
       Triangle{sides=[1, 1, 1]}, 
       Triangle{sides=[1, 3, 3]}] 

です。

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Set; 
public class Triangle 
{ 
    private int[]sides; 
    public Triangle(int x, int y, int z) 
    { 
     sides = new int[]{x,y,z}; 
     Arrays.sort(sides); 
    } 

    public Triangle(String ... args) 
    { 
     this(Integer.parseInt(args[0].trim()), Integer.parseInt(args[1].trim()), Integer.parseInt(args[2].trim())); 
    } 

    @Override 
    public boolean equals(Object o) 
    { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     Triangle triangle = (Triangle) o; 

     if (!Arrays.equals(sides, triangle.sides)) return false; 

     return true; 
    } 

    @Override 
    public int hashCode() 
    { 
     return sides != null ? Arrays.hashCode(sides) : 0; 
    } 

    @Override 
    public String toString() 
    { 
     return "Triangle{" + 
         "sides=" + Arrays.toString(sides) + 
         '}'; 
    } 

    public static void main(String[] args) throws IOException 
    { 

     String[] input = new String[]{ "1,2,1" , "1,1,2", "1,2,3","1,3,1","1,1,1","1,3,3","1,1,3"}; 

     Set<Triangle> triangles = new HashSet<Triangle>(); 
     for (String s : input) 
     { 
      Triangle triangle = new Triangle(s.split(",")); 
     if (triangles.contains(triangle)) 
     { 
      System.out.println("The triangle [" + triangle + "] already exists!"); 
     } 
     triangles.add(triangle); 
     } 
     System.out.println("triangles = " + triangles); 
    } 
} 
+0

私はJavaを学んでいますが、これは私が自分自身を考え出している問題です。私はそれを終えました、そして、あなたが示唆していることは、私が行っていることさえもありません。おそらく、他の場所であなたのスキルを表示したり、答えにつながることによって質問に答えることに固執するべきでしょう。私はこれに感謝しますが、あなたは間違った考えを持っています。 – nmagerko

+0

私はこのサイトを初めて知っていると私はいくつかの焦点を間違えた可能性があります。私はあなたが満たすために空白を残したくないので、私はあなたがjavaを学んでいる感覚を得たので、私はできるだけ完全な答えを出そうとした。私は何らかの方法であなたを侮辱したフィードバックを得ました。私はそれをするつもりはありませんでした。私は、この答えが以前のものよりもJavaに新しい人に向けられているので、よりよく適合すると思うと説明しようとしていました。 –

+0

償いをするために、私は私の答えに "contains"という行を付け加えました。私はその質問にもっと指示したいと思っています。 –

関連する問題