2012-06-24 40 views
33

tôi cần phải sắp xếp danh sách các chuỗi theo thứ tự chữ cái:Cách đơn giản để sắp xếp chuỗi trong (trường hợp nhạy cảm) thứ tự chữ cái

List<String> list = new ArrayList(); 
list.add("development"); 
list.add("Development"); 
list.add("aa"); 
list.add("AA"); 
list.add("Aa"); 

Một cách phổ biến để làm điều đó là sử dụng so sánh:

Collections.sort(list, String.CASE_INSENSITIVE_ORDER); 

Vấn đề của CaseInsensitiveComparator rằng “AA” bằng với “aa”. Strings xuất hiện trong kết quả theo trình tự của việc thêm cho các giá trị giống nhau, và nó không phải là chính xác:

"aa","AA","Aa","development","Development" 
+3

Khi bạn viết rằng điều trị "AA" và "aa" giống “là không đúng”, sau đó định nghĩa chính xác của bạn “thứ tự chữ cái” là gì? Câu trả lời của bạn được bỏ phiếu hàng đầu nhưng chưa được chấp nhận (http://meta.stackexchange.com/q/5234/188688) cho thấy rằng bạn muốn phá vỡ quan hệ bằng cách sử dụng so sánh phân biệt chữ thường "bình thường". Để cung cấp cho bạn ý tưởng về cách phân loại chữ cái phức tạp trong thế giới unicode và với các miền địa phương khác nhau, hãy xem hướng dẫn sử dụng [ICU] (http://site.icu-project.org/) viết về [ collation] (http://userguide.icu-project.org/collation). – MvG

Trả lời

56

Nếu bạn không muốn thêm một sự phụ thuộc vào ổi (mỗi câu trả lời của Michael) sau đó so sánh này là tương đương:

private static Comparator<String> ALPHABETICAL_ORDER = new Comparator<String>() { 
    public int compare(String str1, String str2) { 
     int res = String.CASE_INSENSITIVE_ORDER.compare(str1, str2); 
     if (res == 0) { 
      res = str1.compareTo(str2); 
     } 
     return res; 
    } 
}; 

Collections.sort(list, ALPHABETICAL_ORDER); 

và tôi nghĩ nó chỉ là dễ dàng để hiểu và mã ...

4 dòng cuối cùng của phương pháp này có thể được viết ngắn gọn hơn như sau:

 return (res != 0) ? res : str1.compareTo(str2); 
+1

Tôi sẽ biến điều đó nếu thành một toán tử bậc ba :) Nó sẽ loại bỏ việc phân bổ lại và làm cho mã ngắn hơn. –

+5

@MarkoTopolnik - Tôi cũng thường làm như vậy ... nhưng tôi đã cố gắng làm cho mã dễ hiểu nhất có thể. –

+0

Đồng ý, bằng cách này nó rõ ràng hơn cho người đọc nói chung. –

13

Cách đơn giản để giải quyết vấn đề là sử dụng ComparisonChain từ Ổi http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ComparisonChain.html

private static Comparator<String> stringAlphabeticalComparator = new Comparator<String>() { 
     public int compare(String str1, String str2) { 
      return ComparisonChain.start(). 
           compare(str1,str2, String.CASE_INSENSITIVE_ORDER). 
           compare(str1,str2). 
           result(); 
     } 
}; 
Collections.sort(list, stringAlphabeticalComparator); 

Bộ so sánh đầu tiên trong chuỗi sẽ sắp xếp các chuỗi theo thứ tự không phân biệt chữ hoa chữ thường và bộ so sánh thứ hai sẽ sắp xếp các chuỗi theo thứ tự không phân biệt chữ hoa chữ thường. chuỗi Như trừ xuất hiện trong kết quả theo thứ tự chữ cái:

"AA","Aa","aa","Development","development" 
1

Gần đây tôi đã trả lời một câu hỏi tương tự here. Áp dụng phương pháp tương tự để vấn đề của bạn sẽ mang theo giải pháp:

list.sort(
    p2Ord(stringOrd, stringOrd).comap(new F<String, P2<String, String>>() { 
    public P2<String, String> f(String s) { 
     return p(s.toLowerCase(), s); 
    } 
    }) 
); 
+0

Vấn đề là “AA” bằng với “aa”. Các chuỗi xuất hiện trong kết quả theo thứ tự thêm cho cùng một giá trị và không đúng: "aa", "AA", "Aa", "phát triển", "Phát triển" Bạn nên sử dụng so sánh bổ sung để phân biệt "AA" và "aa". – Michael

+0

Đây là đầu ra của mã trên của tôi: '[AA, Aa, aa, Phát triển, phát triển]'.Phù hợp với những gì mong đợi? – missingfaktor

+0

@Michael, vui lòng xem câu trả lời được liên kết để hiểu cách hoạt động của tính năng này. – missingfaktor

0

Đơn giản chỉ cần sử dụng

java.util.Collections.sort(list) 

mà không cần tham số so sánh String.CASE_INSENSITIVE_ORDER.

-1
import java.util.Arrays; 
import java.util.Scanner; 

public class Test3 { 
    public static void main(String[] args) { 

     String a; 
     String b; 
     try (Scanner scan = new Scanner(System.in)) { 
      a = scan.next(); 
      b = scan.next(); 
     } 
     boolean ret = isAnagram(a, b); 
     System.out.println((ret) ? "Anagrams" : "Not Anagrams"); 

    } 

    static boolean isAnagram(String a, String b) { 
     int l1 = a.length(); 
     int l2 = b.length(); 
     boolean rat = false; 

     if (l1 <= 50) { 
      if (l1 == l2) { 

       char[] chars1 = a.toLowerCase().toCharArray(); 
       char[] chars2 = b.toLowerCase().toCharArray(); 
       Arrays.sort(chars1); 
       Arrays.sort(chars2); 
       String Ns1 = new String(chars1); 
       String Ns2 = new String(chars2); 
       if (Ns1.equals(Ns2)) { 
        rat = true; 
       } 
      } 
     } 
     return rat; 
    } 
} 
Các vấn đề liên quan