2016-06-30 1068 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; 
    } 
} 

逻辑找到字符串数组

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的min和max值。字符串数组中的值a是最小值,但在这种情况下,它将Mary显示为最小值。
任何人都可以告诉我更好的方法来查找字符串数组中的最小值和最大值吗?

回答

3

您得到的输出是正确的输出,因为字符串的自然顺序是字典顺序,其中大写字母在小写字母之前。因此Mary是“最小”字符串。

为了不使用自然排序,请不要使用StringcompareTo方法。相反,您可以实施任何您认为合适的逻辑来确定哪个字符串较小。引入备选排序的一种方法是将Comparator<String>实例传递给您的minmax方法,并使用其compare方法比较String

+0

为什么不显示为目的的现成的比较有帮助。或'Collat​​or.getInstance()'? – Andreas

+0

@Andreas我不确定期望的排序是什么。输出的唯一问题可能是区分大小写的排序,但我无法确定。 – Eran

+0

由于非常有可能是OP所需要的,你应该建议它,而不是(或者除了)只说*“实现你认为合适的任何逻辑”*,这意味着OP将不得不写'比较器'从头开始。这不是很有用。 – Andreas

3

我认为,为了您的目的,最好使用String方法compareToIgnoreCase()

但是,这取决于您了解Minimum stringMaximum 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这可以很容易地使用Lambda表达式来实现:

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()字符串按字母顺序比较,这意味着大写字母出现在小写字母之前,因为这是中的顺序。相反,请执行下列操作之一:

或者,对于一个好的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]; 
} 

或者:`String.CASE_INSENSITIVE_ORDER`:

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]; 
}