2017-02-15 6 views
1

Я много читал об этом в этом форуме и на других форумах, но я до сих пор не могу получить конкретный ответ. Во всяком случае я решил сделать это следующим образом:Java, Сортировка Массив парных разрядов и его индексы

Вот класс держать строку и целое:

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<>();

Тогда я заселить ArrayList так:

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 и doubleles, и я не могу использовать непосредственно свою двойную матрицу, поэтому мне нужно сделать Double.toString(). Результаты сортируются, но не совсем корректны, потому что строковое вычисление из double не очень точное с точки зрения сортировки по двойному номеру.

Любые идеи?

+1

Сортировка лексически, вероятно, не то, что вы хотите. Почему вы не можете использовать парный разряд? Или лучше: что заставляет вас думать, что не можете? «Есть некоторые проблемы с java и doubles» - в основном это разработчики, у которых проблемы с удвоениями, а не с java. – Fildor

+0

@Fildor этой конкретной строки 'return tr2.getToken(). CompareTo (tr1.getToken());' неверно, когда я изменяю все, начиная с типа 'string' и заканчивая' double'. Согласно моей IDE: 'double не может быть разыменован' – Javac

+1

Да, затем измените * эту * строку, чтобы она работала для double. Вы можете использовать Double wrapper, если вам нужно использовать compareTo. – Fildor

ответ

4

Если вы сравниваете double с лексикографически, по их представлению String, возможно, действительно найдете неожиданные результаты.

Вы можете либо:

  • рефакторинга Tuple так что token является double (или обертки Double, если вы хотите, чтобы вызвать compareTo на экземпляре)
  • иначе, в вашем Comparator, вы можете вызвать Double.parseDouble на ваш String s (который должен быть относительно безопасным, так как String s приходят от double s в первую очередь) и вызывают compareTo на возвращенной обертке Double.

Последний вариант звучит довольно некрасиво, потому что у вас есть куча, казалось бы, ненужных преобразований назад и вперед между Double и String и наоборот.

Это также будет означать ухудшение производительности, так как при сортировке вашей коллекции будет вызываться несколько раз при вызове compareTo.

+0

Спасибо за ваш вклад. Что вы подразумеваете под оберткой 'Double'? Я попытался изменить класс 'Tuple'; где 'string', я помещаю' double', но в строке 'return tr2.getToken(). compareTo (tr1.getToken());' я получаю 'double не может быть разыменованной' ошибкой. – Javac

+1

@Javac 'Double'! =' Double' последний примитивен. Вы не можете вызывать функции на нем, как вы пытаетесь. «Двойной» - это оболочка для этого примитивного типа, позволяющая именно это (в числе других целей). Переход формы 'double' к соответствующему' Double' называется «бокс». – Fildor

+0

@Javac, если вы хотите использовать примитивы, вы можете вызывать статический 'Double.compare (double d1, double d2)' вместо вызова 'compareTo'. В противном случае вы можете реорганизовать с помощью оберток «Double», как я уже говорил, и указал Fildor. – Mena

0

Если вам действительно нужно преобразовать двойник в строки, безопаснее использовать

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

, так как он обрабатывает двойную непредсказуемость.

+0

Ну, он не должен этого делать вообще. Сортировка Лексикографически в двухместных номерах, несомненно, принесет сюрпризы. Просто подумайте о значениях, которые будут представлены в математической нотации ... – Fildor

3

Вы можете хранить токен как двойной в своем Tuple и реализовывать интерфейс Comparable. в getToken вы можете вернуть строковое представление двойного в форме, которое вам действительно необходимо.

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

я получил ту же идею, Влад Боченин:

Вы просто реализовать 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

Вы можете хранить токен как двойной в вашем Tuple и реализует интерфейс Comparable. в getToken вы можете вернуть строковое представление двойного в форме, которое вам действительно необходимо.

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

Если вы хотите добавить ссылку на ответ Влада, используйте комментарий. Не копируйте его ответ. – Fildor

Смежные вопросы