2015-06-23 76 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