2015-09-16 2 views
3

Метод compareTo() в Java сравнивает две строки «лексикографически». Может кто-то просто объяснить, как лексикографическое сравнение работает в java?Что такое строка лексикографически? Java

Я нашел this post, который объясняет три случая < 0, == 0 и> 0; Тем не менее, я все еще запутался ...

Означает ли это, что число вернулось, это количество мест, расположенных рядом друг с другом, если они должны быть отсортированы в алфавитном порядке как словарь?

Кроме того, как метод справляется с чувствительностью к регистру? Являются ли строчные буквы первыми в строке перед прописными буквами? Есть ли диаграмма для этого?

Например, приведенный ниже код производит выход -31. Означает ли это, что собака-строка находится в -31 местах от кота?

public static void main(String[] args) { 
    Scanner keyboard = new Scanner(System.in); 

    String str1 = "Dog"; 

    String str2 = "cat"; 

    int result = str1.compareTo(str2); 
    System.out.println(result); 
+3

Вы можете прочитать источник здесь: http://www.docjar.com/html/api/java/lang/String.java.html – PeterMmm

+3

Возвращенное значение очень хорошо задокументировано в классе 'String' –

ответ

2

Возвращаемое значение не имеет значения, как compareTo контракт вернуться отрицательным, положительным или 0 (как вы уже знаете).

Однако, если на самом деле вы хотите понять, почему -31 возвращается при сравнении Dog с cat (или любой другой строки), то вы можете просто посмотреть на метод непосредственно в String классе:

public int compareTo(String anotherString) { 
    int len1 = value.length; 
    int len2 = anotherString.value.length; 
    int lim = Math.min(len1, len2); 
    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; 
} 

Имейте в виду, что value - массив char, поддерживающий строку.

private final char value[]; 

Так как же этот метод дальше?

  • Вы извлекаете минимум как длину строки в переменной lim.
  • Вы создаете копию обоих массивов строковых символов.
  • Вы производите цикл над каждым символом (проверяя, равны ли они) до достижения нижнего предела.
  • Если два символа с одинаковым индексом не равны, вы возвращаете результат вычитания второго в первый. char можно представить как значение int (которое принимает их значение ascii) и уже упорядочено. Таким образом, когда вычитание отрицательного числа будет возвращено, если второй символ «выше», то первый. Положительный будет возвращен, если второй символ «ниже», а затем первый. 0 будет возвращено, если оба равны.
  • Если все символы были равны во время цикла для наименьшей длины строки, вы возвращаете вычитание обеих длин.

В вашем примере, первая буква обоих слов не равна, так что вы получите, чтобы сравнить D с c, которые соответственно представлены в виде 68 и 99. Substract от 99 до 68, и вы получите -31.

Так, чтобы ответить на этот вопрос:

Означает ли это, что ИНТ возвращенное количество мест далеко в строки формы друг друга, если они должны были быть отсортированы в алфавитном порядке как словарь?

Нет, это на самом деле либо разница между двумя значениями ascii, не совпадающими с символом, либо разностью обеих длин.

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

Если вы хотите проигнорировать случай сравнения, вы можете использовать String#compareToIgnoreCase.

Также вы можете проверить this chart на значения ascii (верхний и нижний регистр).

+0

Очень хороший ответ Жан Благодарю. Полюбите, как вы объяснили код метода по строкам. Единственный вопрос, который у меня сейчас есть: как получилось, что это изменило только первые персонажи?68-99 = -31. Разве он не должен продолжать сравнивать остальных персонажей, таких как «o» и «a», а «g» - «t»? – JonathanScialpi

+1

@JonathanScialpi Нет, нет смысла сравнивать остальную часть строки. Нам просто нужно проверить разницу первого символа, который не прошел тест равенства, поскольку это единственный символ, который имеет значение при упорядочивании по алфавиту строки. –

1

Я нашел Wikipedia's Definition of Lexicographical order очень полезно в ответе на ваш вопрос.

Проще говоря, сравнение представляет собой числовой результат, сделанный с использованием алфавита. В алфавитном сравнении мы сравниваем упорядоченный набор букв, которые составляют последовательность (обычно слова или строки). Возвращаемое значение будет равно 0, если два равны, и < или> в зависимости от того, какое значение соответствует алфавиту до или после другого.

взять список слов:

  • кошка
  • собака
  • животное
  • муравьеда

Если мы сравним эти, мы берем первый символ каждого и смотреть. Когда мы сравниваем «cat» и «dog», мы берем первый символ «c» и «d» и сравниваем их. Численно в коде простой (не обязательно лучший) способ сделать это - преобразовать их в числовое значение и вычесть одно значение из другого. Это будет равно 0, если они будут одинаковыми, и мы перейдем к сравнению следующего символа в каждом. Если они разные, то мы знаем, что они лексикографически (в алфавитном порядке) после другого.

Возвращаемое значение не требуется, чтобы иметь проницательную информацию. Вот почему единственные значения, которые означают что-либо: < 0, == 0, и> 0.

Что касается корпуса, то это деталь реализации. Существуют компараторы, которые считают, что верхний регистр «А» будет таким же, как в нижнем регистре «а», и есть компараторы, которые этого не делают, поскольку они имеют разные числовые значения. (См .: How to sort alphabetically while ignoring case sensitive?).

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