2016-06-30 3 views
0

Я новичок в программировании в Java. Следующий исходный код находится в книге, когда я пытаюсь выполнить программу, он показывает некоторые неправильные данные.Java - Найти минимальное и максимальное значение массива строк

public class Pair<T> { 

    private T first; 
    private T second; 

    public Pair() { 
     first = null; 
     second = null; 
    } 

    public Pair(T first, T second) { 
     this.first = first; 
     this.second = second; 
    } 

    public T getFirst() { 
     return first; 
    } 

    public T getSecond() { 
     return second; 
    } 

    public void setFirst(T newValue) { 
     first = newValue; 
    } 

    public void setSecond(T newValue) { 
     second = newValue; 
    } 
} 

Logic найти минимальное и максимальное значение массива строк

public class ArrayAlg { 

    public static Pair<String> minmax(String[] arr) { 
     if (arr == null || arr.length == 0) 
      return null; 

     String min = arr[0]; 
     String max = arr[0]; 

     for (int i = 1; i < arr.length; i++) { 
      if (min.compareTo(arr[i]) > 0) 
       min = arr[i]; 
      if (max.compareTo(arr[i]) < 0) 
       max = arr[i]; 
     } 
     return new Pair<String>(min, max); 

    } 
} 

public static void main(String[] args) { 

     String[] words = { "Mary", "had", "a", "little", "lamb" }; 
     Pair<String> obj = ArrayAlg.minmax(words); 
     System.out.println("Minvalue " + obj.getFirst()); 
     System.out.println("Maxvalue " + obj.getSecond()); 

    } 

Если выполнить вышеуказанную программу, она показывает Minvalue = Mary and MaxValue = little. Значение a в массиве String является минимальным значением, но в этом случае оно отображает Mary в качестве минимального значения.
Может ли кто-нибудь сказать мне лучший подход найти минимальное и максимальное значение в массиве String?

ответ

3

Выход, который вы получили, является правильным выходом, так как естественный порядок строк является лексикографическим порядком, в котором буквы верхнего регистра поступают перед строчными буквами. Следовательно, Mary является «самой маленькой» строкой.

Для того, чтобы не использовать естественный порядок, не используйте метод StringcompareTo. Вместо этого вы можете реализовать любую логику, которая вам подходит, чтобы определить, какая строка меньше. Один из способов введения альтернативного заказа - передать экземпляр Comparator<String> на ваш метод minmax и использовать его метод compare для сравнения String.

+0

Почему бы не помочь, показывая легкодоступного компаратор для цели: 'String.CASE_INSENSITIVE_ORDER'. Или 'Collator.getInstance()'? – Andreas

+0

@ Andreas Я не уверен, что это за заказ. Вполне возможно, что единственной проблемой с выходом был чувствительный к регистру порядок, но я не могу быть уверен в этом. – Eran

+0

Поскольку существует очень высокая вероятность, что именно то, что требуется OP, вы должны предложить это, а не (или в дополнение к) только сказать * «реализовать любую логику, которую вы сочтете нужным» *, подразумевая, что OP должен был бы написать «Comparator» с нуля. Это не очень полезно. – Andreas

3

Думаю, для вас лучше использовать String способ compareToIgnoreCase().

Но это зависит от вас, что вы понимаете, что такое Minimum string и Maximum string есть.

Кроме того, существует возможность сравнить любые объекты - через Comparator.

public static Pair<String> minmax(String[] arr) { 
    if (arr == null || arr.length == 0) 
     return null; 

    Arrays.sort(arr, new Comparator<String>() { 
     @Override 
     public int compare(String o1, String o2) { 
      return o1.compareToIgnoreCase(o2); // to compare by lexicographical order 
      //return o1.length() - o2.lenth(); // to compare by length 
     } 
    }); 

    return new Pair<String>(arr[0], arr[arr.length - 1]); 
} 

Вот некоторые ссылки, чтобы следовать:

+0

Можете ли вы, пожалуйста, изменить код и обновить его на основании поставленного выше вопроса – Aishu

+0

Я не знаю, как изменить, – Aishu

+0

@Aishu, я немного изменил ваш код с минимальными изменениями. – ar4ers

1

Вам нужно будет использовать Comparator для этого. Вы можете сортировать слова в алфавитном порядке, игнорируя регистр, используя String.CASE_INSENSITIVE_ORDERComparator.

В Java 8 это может быть достигнуто легко с помощью Лямбда:

public final Pair<String> miniMax(final String[] words) { 
    final String min = Arrays.stream(words).min(String.CASE_INSENSITIVE_ORDER).orElse(null); 
    final String max = Arrays.stream(words).max(String.CASE_INSENSITIVE_ORDER).orElse(null); 
    return new Pair<>(min, max); 
} 

Тестирование:

String[] words = { "Mary", "had", "a", "little", "lamb" }; 
System.out.println(miniMax(words)); 

Выход:

a, Mary 
1

compareTo() сравнивает строки лексикографически, что означает, что заглавные буквы приходят до строчных букв, так как это порядок в Unicode.Вместо этого выполните одно из следующих действий:

  • Использование compareToIgnoreCase()

  • Используйте регистронезависимым Comparator, легко доступны из String.CASE_INSENSITIVE_ORDER

  • Использование полного конкретного языка Comparator, что закажет специальное символов и международных писем, как вы бы указали в книжном индексе, доступном от Collator.getInstance()

В качестве альтернативы для хорошей реализации Java 8 см. answer by arizzle.

Таким образом, ваш цикл может быть:

for (int i = 1; i < arr.length; i++) { 
    if (min.compareToIgnoreCase(arr[i]) > 0) 
     min = arr[i]; 
    if (max.compareToIgnoreCase(arr[i]) < 0) 
     max = arr[i]; 
} 

Или:

Comparator<String> comp = Collator.getInstance(); 
for (int i = 1; i < arr.length; i++) { 
    if (comp.compare(min, arr[i]) > 0) 
     min = arr[i]; 
    if (comp.compare(max, arr[i]) < 0) 
     max = arr[i]; 
} 
Смежные вопросы