2016-06-30 39 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を表示する最小値と最大値を検索します。文字列配列の値aは最小値ですが、この場合は最小値としてMaryが表示されます。
String配列の最小値と最大値を見つけるより良い方法を教えてもらえますか?

答えて

3

文字列の自然順序付けは大文字が小文字の前に来る辞書順ですので、得られた出力は正しい出力です。したがって、Maryは「最小」の文字列です。

自然順序付けを使用しないようにするには、StringcompareToメソッドを使用しないでください。代わりに、どの文字列が小さいかを判断するのに適したロジックを実装することができます。代わりの注文を導入する1つの方法は、Comparator<String>インスタンスをminmaxメソッドに渡し、compareメソッドを使用してStringを比較することです。

+0

目的のために容易に利用可能なコンパレータを示すことによって助けないのはなぜ。または 'Collat​​or.getInstance()'? – Andreas

+0

@アンドレアス希望の注文が何であるか分かりません。出力に関する唯一の問題は、大文字と小文字を区別した順序である可能性がありますが、私はそれを確信できません。 – Eran

+0

オペレーションが必要とする可能性が非常に高いので、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で

これはラムダを使用して容易に実現することができます。

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。代わりに、次のいずれかの操作を行います。

また、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]; 
} 
関連する問題