2017-02-15 10 views
1

私はこのフォーラムや他のフォーラムでこれについて多くを読んだことがありますが、まだ具体的な答えを得ることはできません。とにかく私はこのようにそれを行うことを決めた。ここではJava、Sort二重配列とそのインデックス

は、文字列と整数を保持するクラスです:

public class Tuple{ 

    private String token; 
    private int docID; 



    public Tuple(String token, int docID) { 
     this.token = token; 
     this.docID = docID; 
    } 

    public String getToken() { 
     return token; 
    } 
    public void setToken(String token) { 
     this.token = token; 
    } 
    public int getDocID() { 
     return docID; 
    } 
    public void setDocID(int docID) { 
     this.docID = docID; 
    } 

} 

そして、私はこれらのタプルにprivate ArrayList<Tuple> temps = new ArrayList<>();

を置くために、配列リストを作成しますそして、私はこのような配列リストを読み込む:

012:

for (int i = 0; i < numberOfDocs; i++) 
{ 
    Tuple cat = new Tuple(Double.toString(vect[i]),i); 
    temps.add(cat); 
} 

結局、私はこのような配列をソートしています

public void sortTmp() 
{ 
    Collections.sort(temps, new Comparator<Tuple>() 
    { 
     @Override 
     public int compare(Tuple tr2, Tuple tr1) 
     { 
      return tr2.getToken().compareTo(tr1.getToken()); 
     } 
    }); 
} 

javaとdoubleには問題があり、私はダブルマトリックスを直接使うことができないので、私はDouble.toString()をしなければなりません。結果はソートされますが、ダブルからの文字列の計算は倍精度ソートの点で非常に正確ではないため、完全には正しくありません。

アイデア?

+1

あなたが望むものはおそらくではありません。なぜダブルスを使用できないのですか?またはそれより優れている:あなたができないと思うものは何ですか? "javaとdoubleにはいくつかの問題があります" - 主にJavaではなくdoubleに問題がある開発者です。 – Fildor

+0

この特定の行 'return tr2.getToken()。compareTo(tr1.getToken());'は、 'string'型から' double'型にすべて変更すると間違っています。私のIDEによれば、「ダブルは参照解除できません。」 – Javac

+1

はい、*その行をダブルに変更するように変更してください。 compareToを使用する必要がある場合は、Doubleラッパーを使用できます。 – Fildor

答えて

4

doubleを辞書編集で比較している場合は、Stringという表現では予期しない結果が生じることがあります。

次のいずれかの可能性:tokendouble(またはインスタンス上compareToを起動したい場合はDoubleラッパー)となるように、

  • リファクタリングTuple
  • そうでない場合は、あなたのComparatorに、あなたは上のDouble.parseDoubleを呼び出すことができますStringStringが最初にdoubleであるため、比較的安全であるはずです)、返されたDoubleラッパーでcompareToを呼び出します。

あなたはDoubleStringおよびその逆の間一見不必要な前後の変換の束を持っているので、最後のオプションは非常に醜いですね。

また、コレクションのソート時にcompareToが複数回呼び出されるため、パフォーマンスが低下する可能性があります。

+0

入力いただきありがとうございます。ラッパー 'ダブル'はどういう意味ですか?私は 'Tuple'クラスを変更しようとしました。 'string'は' double'を置いていますが、 'return tr2.getToken()。compareTo(tr1.getToken());' '二重引用符は参照解除できません。 – Javac

+1

@Javac 'Double'!=' double'後者はプリミティブです。あなたがしようとしているように、関数を呼び出すことはできません。 'Double'は、このプリミティブ型のラッパーで、これを(他の目的の間で)正確に許可します。 「ダブル」をその対応する「ダブル」にすることを「ボクシング」と呼ぶ。 – Fildor

+0

@Javacプリミティブを使いたい場合、 'compareTo'を呼び出すのではなく、静的' Double.compare(double d1、double d2) 'を呼び出すことができます。そうでなければ、私が言っていたように 'Double'ラッパーでリファクタリングすることができ、Fildorも指摘しました。 – Mena

0

あなたが本当に文字列にダブルスを変換する必要がある場合、それは二重の予測不可能性を扱うため、

BigDecimal.valueOf(vect[i])).toString(); 

を使用する方が安全です。

+0

まあ、彼はまったくそれをすべきではありません。レキシカルで2倍にソートすると、必ず驚きが導入されます。数学記法で表現される値を考えてみてください... – Fildor

3

Tupleにトークンを2重に格納し、Comparableインターフェイスを実装できます。 getTokenでは実際に必要とされている形式の文字列をdouble形式で返すことができます。

public class Tuple implements Comparable<Tuple>{ 

    private double token; 
    private int docID; 

    public Tuple(double token, int docID) { 
     this.token = token; 
     this.docID = docID; 

    } 

    public String getToken() { 
     return String.valueOf(token); 
    } 
    public void setToken(double token) { 
     this.token = token; 
    } 
    public int getDocID() { 
     return docID; 
    } 
    public void setDocID(int docID) { 
     this.docID = docID; 
    } 

    @Override 
    public int compareTo(Tuple o) { 
     return Double.compare(this.token, o.token); 
    } 
} 
0

私は、ヴラドBocheninと同じ考え方だ:あなたはちょうどComparableを実装し、compareToを上書き

を:

public class Tuple implements Comparable<Tuple> { 

    public Double token; 
    public int docID; 

    public Tuple(final double token, final int docID) { 
     this.token = token; 
     this.docID = docID; 
    } 

    @Override 
    public int compareTo(final Tuple o) { 
     return this.token.compareTo(o.token); 
    } 
} 

とユニットテスト:あなたが保存することができます

public class TestTuple { 

    @Test 
    public void testSort() { 
     final Random r = new Random(System.currentTimeMillis()); 
     final int numberOfDocs = 100; 
     final ArrayList<Tuple> temp = new ArrayList<Tuple>(); 
     for (int i = 0; i < numberOfDocs; i++) { 
      temp.add(new Tuple(r.nextDouble(), i)); 
     } 
     Collections.sort(temp); 

     Tuple old = temp.get(0); 
     // test if sorted 
     for (final Tuple next : temp) { 
      Assert.assertTrue(next.token >= old.token); 
      old = next; 
     } 
    } 
} 
-1

あなたのタプルでトークンをdoubleとして扱い、Comparableインタフェースを実装します。 getTokenでは、実際に必要とされる形式のdouble型の文字列を返すことができます。字句を並べ替え

private double token; 
private int docID; 

public Tuple(double token, int docID) { 
    this.token = token; 
    this.docID = docID; 

} 

public String getToken() { 
    return String.valueOf(token); 
} 
public void setToken(double token) { 
    this.token = token; 
} 
public int getDocID() { 
    return docID; 
} 
public void setDocID(int docID) { 
    this.docID = docID; 
} 

@Override 
public int compareTo(Tuple o) { 
    return Double.compare(this.token, o.token); 
} 

}

To see More about CompareTo

+0

これは私の答え(と私の貧しい英語)のコピーです。それは冗談ですか? –

+0

Vladの答えへのリンクを追加する場合は、コメントを使用します。彼の答えをコピーしないでください。 – Fildor

関連する問題