2015-06-23 70 views
18

我現在正面臨一個問題。在我的一個程序中,我需要從數組中刪除具有相同字符的字符串。例如。假設,在字符串數組中刪除具有相同字符的字符串

我有3個數組一樣,

String[] name1 = {"amy", "jose", "jeremy", "alice", "patrick"}; 
String[] name2 = {"alan", "may", "jeremy", "helen", "alexi"}; 
String[] name3 = {"adel", "aron", "amy", "james", "yam"}; 

正如你所看到的,是name1陣列中的String amy。另外,在接下來的兩個數組中,我有類似may,amyyam的字符串。我需要的是,我需要一個不包含這些重複字符串的最終數組。我只需要一次發生:我需要刪除最終數組中所有名稱的排列。這是最終的陣列應該是:

String[] finalArray={"amy", "jose", "alice", "patrick","alan", "jeremy", "helen", "alexi","adel", "aron", "james"} 

(上面的數組中刪除了山藥,可能,只包括amy)。

我至今嘗試過,使用HashSet,是如下

String[] name1 = {"Amy", "Jose", "Jeremy", "Alice", "Patrick"}; 
String[] name2 = {"Alan", "mAy", "Jeremy", "Helen", "Alexi"}; 
String[] name3 = {"Adel", "Aaron", "Amy", "James", "Alice"}; 
Set<String> letter = new HashSet<String>(); 
for (int i = 0; i < name1.length; i++) { 
    letter.add(name1[i]); 
} 
for (int j = 0; j < name2.length; j++) { 
    letter.add(name2[j]); 
} 
for (int k = 0; k < name3.length; k++) { 
    letter.add(name3[k]); 
} 
System.out.println(letter.size() + " letters must be sent to: " + letter); 

但是,這段代碼的問題是,它只是刪除了相同字符串的多次出現。還有其他的選擇嗎?很感謝任何形式的幫助。

回答

8

TreeSet允許我們給一個比較器。看看這是否有幫助。保持計數使用TreeMap

package empty; 

import java.util.Arrays; 
import java.util.Comparator; 
import java.util.Set; 
import java.util.TreeMap; 
import java.util.TreeSet; 

public class RemoveDuplicateStrings { 

    public static void main(String[] args) { 
     String[] name1 = { "amy", "jose", "jeremy", "alice", "patrick" }; 
     String[] name2 = { "alan", "may", "jeremy", "helen", "alexi" }; 
     String[] name3 = { "adel", "aron", "amy", "james", "yam" }; 

     Comparator<String> comparator = new Comparator<String>() { 
      @Override public int compare(String o1, String o2) { 
       System.out.println("Compare(" + o1 + "," + o2 + ")"); 
       char[] a1 = o1.toCharArray(); 
       Arrays.sort(a1); 
       char[] a2 = o2.toCharArray(); 
       Arrays.sort(a2); 
       return new String(a1).compareTo(new String(a2)); 
      } 
     }; 
     Set<String> set = new TreeSet<String>(comparator); 

     for (String name : name1) { 
      set.add(name); 
     } 
     for (String name : name2) { 
      set.add(name); 
     } 
     for (String name : name3) { 
      set.add(name); 
     } 

     String[] result = set.toArray(new String[set.size()]); 
     System.out.println(Arrays.asList(result)); 

     // Using TreeMap to keep the count. 

     TreeMap<String, Integer> map = new TreeMap<String, Integer>(comparator); 

     addAll(name1, map); 
     addAll(name2, map); 
     addAll(name3, map); 

     System.out.println(map); 
    } 

    private static void addAll(String[] names, TreeMap<String, Integer> map) { 
     for (String name : names) { 
      if (map.containsKey(name)) { 
       int n = map.get(name); 
       map.put(name, n + 1); 
      } else 
       map.put(name, 1); 
     } 
    } 
} 
+0

很好的答案..工作真的很棒.. Tkykyou ..:) – Lal

+1

相反_slow_雖然 - 它會將每個比較的字符串進行排序,並且會有很多比較。您應該創建「標準化」的數據集合,然後進行組合。 –

+0

@KDM有沒有可能從你的答案中得到每個字符串的出現次數? – Lal

10

您可以對字符串的字符數組(str.toCharArray())進行排序,並從排序的數組中創建一個新的字符串以獲取字符串的「規範」表示形式。

然後,您可以將這些字符串添加到Set,並檢查每個字符串標準表示是否已經在Set中。

Set<String> letter = new HashSet<String>(); 
for (int i = 0; i < name1.length; i++) { 
    char[] chars = name1[i].toCharArray(); 
    Arrays.sort(chars); 
    letter.add(new String(chars)); 
} 
for (int j = 0; j < name2.length; j++) { 
    char[] chars = name2[j].toCharArray(); 
    Arrays.sort(chars); 
    letter.add(new String(chars)); 
} 
for (int k = 0; k < name3.length; k++) { 
    char[] chars = name3[k].toCharArray(); 
    Arrays.sort(chars); 
    letter.add(new String(chars)); 
} 

編輯:我改變了Set<char[]>Set<String>,因爲數組不會覆蓋hashCodeequals,所以HashSet<char[]>是行不通的。

+0

好.. :)想像一個不錯的解決方案..Thankyou .. :)將盡快更新你... – Lal

+0

另一個疑問..例如,如果字符串數組的內容是,A = { 「1 2 3 4」,「5 6 7 8」,「3 4 2 1」},那麼這個e怎麼做? – Lal

+0

@Lal實際上,在將它放入Set之前,您應該將char []轉換回String,因爲數組不會覆蓋equals和hashCode – Eran

2

在符合KDM:

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

public class RemoveDuplicateString { 

    private static boolean add(Set<String> keySet, String s){ 
     char[] sortCharacters = s.toCharArray(); 
     Arrays.sort(sortCharacters); 
     return keySet.add(new String(sortCharacters)); 
    } 

    private static void check(Set<String> keySet, String []names, List<String> result){ 
     for (String name : names) { 
      if (add(keySet, name)){ 
       result.add(name); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     String[] name1 = {"amy", "jose", "jeremy", "alice", "patrick"}; 
     String[] name2 = {"alan", "may", "jeremy", "helen", "alexi"}; 
     String[] name3 = {"adel", "aron", "amy", "james", "yam"}; 
     Set<String> keySet = new HashSet<String>(); 
     List<String> result = new ArrayList<String>(); 
     check(keySet, name1, result); 
     check(keySet, name2, result); 
     check(keySet, name3, result); 
     System.out.println(result); 
    } 
} 
1

一種替代,爪哇8,解決方案。

1)創建與所述歸一化形式的Map<String, List<String>然後將所有看到不同的形式

public static Map<String, List<String>> groupNormalised(final String[]... input) { 
    return Arrays.stream(input) 
      .flatMap(Arrays::stream) 
      .collect(Collectors.groupingBy(s -> { 
       char[] c = s.toCharArray(); 
       Arrays.sort(c); 
       return new String(c); 
      })); 
} 

實施例:

Map<String, List<String>> grouped = groupNormalised(name1, name2, name3);   
grouped.forEach((k, v) -> System.out.printf("%s appears as %s%n", k, v)); 

輸出:

eejmry appears as [jeremy, jeremy] 
aceil appears as [alice] 
eehln appears as [helen] 
ejos appears as [jose] 
adel appears as [adel] 
aeilx appears as [alexi] 
acikprt appears as [patrick] 
aejms appears as [james] 
amy appears as [amy, may, amy, yam] 
anor appears as [aron] 
aaln appears as [alan] 

2)處理Map提取數據要

現在你有一個選擇,你可以創建的標準化形式的一個Set

final Set<String> normalisedForms = grouped.keySet(); 

或者你可以創建第一個遇到的Set

final Set<String> first = grouped.values().stream() 
     .map(c -> c.iterator().next()) 
     .collect(toSet()); 

或者作爲數組:

final String[] first = grouped.values().stream() 
     .map(c -> c.iterator().next()) 
     .toArray(String[]::new); 
+0

可能是一個工作解決方案..但我正在尋找解決方案在jdk7 ..感謝您的答覆.. – Lal

+0

@ Lal,除非你有足夠的理由堅持使用Java 7,否則我會建議你開始升級到Java 8.它已經出來了一年多了...... –

+0

是的..計劃學習jdk 8 .. @Boristhespider – Lal