2015-12-16 13 views
10

Tôi muốn thêm các chữ cái của một chuỗi vào một danh sách, nhưng tôi chỉ muốn thêm từng chữ cái một lần. Ví dụ: nếu Chuỗi là "HELLO AM CHRISTOS WHITE", một số chữ cái xuất hiện nhiều lần, vì vậy tôi muốn chúng chỉ được thêm một lần.Thêm các chữ cái duy nhất của một Chuỗi đã cho vào Danh sách

Tôi đang nghĩ về hai cho vòng:

for (int i=0; i< str.length(); i++){ 
    for(int j=0; j< str.length(); j++){ 
     if (str.charAt(i) != str.charAt(j)) { 
      myList.add(charAt(i)); 
     } 
    } 
} 

Nhưng mã này không tránh trùng lặp.

+0

Tại sao lại là hai vòng? lặp lại trên một bản gốc đơnLine.toCharArray(); if (! listContains (Char.valueOf (char [i])) addChar(); – Stultuske

+3

Ngoài ra, bạn có thể sử dụng một 'Tập' để đạt được tính độc đáo của nội dung của nó –

Trả lời

14

Nó sẽ hiệu quả hơn để sử dụng một LinkedHashSet để xác định những nhân vật độc đáo. Nếu bạn sử dụng LinkedHashSet, thứ tự của các ký tự duy nhất của chuỗi đầu vào sẽ được giữ nguyên.

Sau một vòng lặp, sẽ mất thời gian tuyến tính, bạn có thể thêm tất cả các ký tự duy nhất vào đầu ra List.

Set<Character> unique = new LinkedHashSet<>(); 
for (int i = 0; i < str.length(); i++){ 
    unique.add(str.charAt(i)); 
} 
myList.addAll(unique); 
12

Để tránh trùng lặp trong bộ sưu tập, bạn không cần List, bạn cần Set (chẳng hạn như HashSet).

Nếu bạn muốn giữ nguyên thứ tự bạn đang thêm String s, hãy sử dụng LinkedHashSet.

Cuối cùng, nếu bạn muốn Set để tự động sắp xếp String s (hoặc để có thể sắp xếp chúng với Comparator), hãy sử dụng TreeSet.

Ví dụ

String foo = "ghghababcdef"; 
Set<String> hash = new HashSet<>(); 
Set<String> linked = new LinkedHashSet<>(); 
Set<String> tree = new TreeSet<>(); 
// iterating characters 
for (char c: foo.toCharArray()) { 
    // adding String representation of character to each set 
    hash.add(Character.toString(c)); 
    linked.add(Character.toString(c)); 
    tree.add(Character.toString(c)); 
} 
// printing... 
System.out.println(hash); 
System.out.println(linked); 
System.out.println(tree); 

Output

[a, b, c, d, e, f, g, h] // this may vary 
[g, h, a, b, c, d, e, f] // keeps insertion order 
[a, b, c, d, e, f, g, h] // sorted lexicographically by default 
4

thay thế cho câu hỏi Set nếu bạn muốn gắn bó với giải pháp List. Bạn chỉ cần lặp lại một lần và sử dụng phương thức List.contains(Object) và kiểm tra xem hiện tại char đã có mặt trong số List của bạn chưa.

String str = "HELLO AM CHRISTOS WHITE"; 
List<Character> myList = new ArrayList<>(); 
for(int i=0; i< str.length(); i++){ 
    if (!myList.contains(str.charAt(i))) { 
     myList.add(str.charAt(i)); 
    } 
} 
for(char c : myList) { 
    System.out.println(c); 
} 

đầu ra

HELO AMCRISTW

0

j không được gán. Tôi đoán nó được khởi tạo đến 0 vì vậy không có ngoại lệ

Nếu bạn thay đổi vòng lặp thứ hai thành for(int j=0; j< str.length(); j++) nó sẽ vẫn không hoạt động, nó sẽ không in bất kỳ chữ cái nào được sao chép trong chuỗi.

Vì vậy, hãy nghĩ về phạm vi j cần lặp lại. Bạn muốn in bất kỳ chữ cái nào chưa xuất hiện trong chuỗi, nếu bạn có được jist của tôi.

+0

Đó chỉ là một ví dụ trong chương trình của tôi là chính xác. –

+0

@ChristosMichael: Trong trường hợp đó, bạn nên chấp nhận câu trả lời phù hợp nhất với câu hỏi của mình. Câu hỏi của tôi?] (http://stackoverflow.com/help/someone-answers) – IInspectable

+0

Câu trả lời của tôi đã giải quyết được lỗi trong mã mà bạn đã cung cấp, làm cách nào để biết bạn có gì trong chương trình của mình. muốn giải quyết vấn đề trong logic được triển khai, không nhận ra bạn có các tùy chọn khác để sử dụng các cấu trúc dữ liệu nổi tiếng. –

0

Đáng tiếc là không có dòng nhân vật trong Java 8 nhưng đây là một cách Java 8:

str.chars().distinct().mapToObj(c -> (char) c).collect(Collectors.toList()); 

Nó có thể là kém hiệu quả nhưng nó là một thể đọc được một lót và nó cho thấy sức mạnh của con suối.

Các vấn đề liên quan