Java CompareTo для аргументов String и Integer - PullRequest
2 голосов
/ 23 мая 2009

Я реализую алгоритм пузырьковой сортировки и хочу, чтобы он мог принимать параметры Integer и String. Я приведу все входные данные как строки и использую метод compareTo для сравнения целых чисел, приведенных в виде строк, со строками. Я получаю неправильный ответ при использовании compareTo для сравнения приведенных целых чисел. Что я делаю не так?

Ответы [ 7 ]

7 голосов
/ 23 мая 2009

Integer.compareTo численно сортирует числа. Это то, что вы хотите.

String.compareTo сортирует строки лексикографически; в алфавитном порядке.

Я помню в Windows 3.1, что папка с фотографиями с моей цифровой камеры была упорядочена следующим образом: ФОТО1, ФОТО10, ФОТО100, ФОТО2, ФОТО20, ФОТО3, ... и так далее. Windows XP сортирует их больше, чем вы ожидаете: PHOTO1, PHOTO2, PHOTO3, ... и т. Д. Это потому, что в ней есть специальные правила сортировки для строк, представляющих числа.

В лексикографическом порядке каждый символ в одной строке A сравнивается с соответствующим символом в другой строке B. Для каждого соответствующего символа в двух строках:

  • Если текущий символ A лексикографически меньше (предшествует в алфавите) символа B, то A предшествует B.
  • Если символ B меньше, чем персонаж A, то B предшествует A.
  • Если два символа одинаковы, то мы пока не знаем. Следующий проверен.
  • Если в одной из строк больше не осталось символов, то более короткий предшествует более длинному.
  • Если в обеих строках больше не осталось символов, значит, это одна и та же строка.

Четвертый пункт здесь - почему вы получаете неправильные ответы, предполагая, что анализ вашей проблемы Эдди правильно.

Рассмотрим строки «10» и «2». Лексикографический порядок будет выглядеть по первым буквам каждого, «1» и «2» соответственно. Символ «1» стоит перед «2» в наборе символов, который используется Java, поэтому он сортирует «10» перед «2», так же, как «голый» сортируется перед «зайцем», потому что «b» предшествует » ч.

Я предлагаю вам привести ваши строки к целым числам перед сортировкой. Для этого используйте Integer.parseString.

2 голосов
/ 23 мая 2009

Вы уверены, что хотите смешать целые числа и строки в одном списке? если так, целые числа меньше или больше чем Строки? что это за особые критерии сортировки?

Вы также можете создать метод пузырьковой сортировки, который сортирует отдельные списки Integer и списки String (и списки любого другого класса). Для этого вы можете использовать Generics. например:

public static <T> void bubbleSort(List<T> elements, Comparator<T> comparator) {
    // your implementation
}

Вы используете параметр comparator для сравнения elements, поэтому они могут быть целыми числами или строками (не оба одновременно). компилятор не позволит вам [без предупреждения] передать список объектов одного класса и компаратор другого класса, поэтому сравнение всегда будет работать.

0 голосов
/ 16 ноября 2015

Именно из-за приведенного ниже кода java API в классе String сравнивается только минимальная длина символов между двумя строками.

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2); //**HERE**
    char v1[] = value;
    char v2[] = anotherString.value;

    int k = 0;
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) {
            return c1 - c2;
        }
        k++;
    }
    return len1 - len2;
}

Если мы используем этот API для сравнения

String first = "ABCD"; 
String second = "ABZ"; 
System.out.println("" + "ABCD".compareTo("ABZ")); //-23

вернет отрицательное значение, говоря, что ABCD меньше, чем ABZ, означает, что C меньше, чем Z, и игнорирует D в первой строке.

Так что, может быть, нам нужно что-то вроде ниже

class StringNumericComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        int len1 = o1.length();
        int len2 = o2.length();
        if(len1 != len2) {
            return len1 - len2; //Else iterate all diff lengh chars and SUM it.
        }
        int lim = Math.min(len1, len2);
        char v1[] = o1.toCharArray();
        char v2[] = o2.toCharArray();

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return 0;
    }
}
0 голосов
/ 23 мая 2009

Предполагая, что вы действительно имеете в виду, что вы конвертируете целые числа в строки, а затем сравниваете, это не сработает. Например, допустим, у вас есть целое число 1234 и целое число 1 и целое число 2. Если вы преобразуете их в строки и сравниваете их, вы получите заказ:

1
1234
2

, что правильно для сортировки ASCII и неправильно для числовой сортировки. То есть я предполагаю, что ваш код делает что-то вроде этого:

public int myCompare(Integer a1, Integer a2) {
    myCompare(String.valueOf(a1), String.valueOf(a2));
}

public int myCompare(String a1, String a2) {
    ....
}

Почему я так предполагаю? Потому что вы говорите о получении неверного результата, а не о получении исключений. Если вы на самом деле получаете исключения, тогда другие постеры верны, что кастинг не будет работать.

0 голосов
/ 23 мая 2009

Сначала вы хотите Comparator not Comparable , потому что Comparator принимает два объекта, тогда как Comparable сравнивает текущий объект с переданным, и вы не можете изменить метод compareTo () для String или Целое число так:

public class CompareIntegersAsStrings implements Comparator {
  public int compare(Object o1, Object o2) {
    return o1.toString().compareTo(o2.toString());
  }
}
0 голосов
/ 23 мая 2009

То, что вы описываете, на самом деле не возможно ... поэтому, возможно, вам нужно опубликовать код. Вот моя интерпретация того, что вы делаете:

public int compareTo(final Object o)
{
    final String str;

    str = (String)o; // this will crash if you pass it an Integer.

    // rest of the code.
}

Документация для сравнения здесь , вы действительно должны следовать контракту.

0 голосов
/ 23 мая 2009

Возьмите экземпляр Comparable.

Строки не могут быть преобразованы в целые числа, и нет метода сравнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...