给定一个字符串的集合,格式如:
{aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh}
要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应
输出
{aaa bbb ccc ddd hhh},{eee fff}, {ggg}
(1)请描述你解决这个问题的思路;
(2)请给出主要的处理流程,算法,以及算法的复杂度
(3)请描述可能的改进(改进的方向如效果,性能等等,这是一个开放问题)。
这里有博主写过一篇 http://blog.csdn.net/lillllllll/article/details/4162605
我这里写一个用javaApi完成的例子, 主要用到Collections 中的方法
欢迎同学们一起交流学习java 。
package collection;
/*给定一个字符串的集合,格式如:
{aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh}
要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应
输出
{aaa bbb ccc ddd hhh},{eee fff}, {ggg}
我的解题思路:
1:要合并首先要判断是否有重复,即一个集合中是否包含另外一个集合中的元素。这让我想起了集合的工具类 Collections
查阅文档还真有一个这样的方法 Collections.disjoint(s1, s2);//没有相同元素返回true 这样就解决了判断重复问题
文档描述:
public static boolean disjoint(Collection<?> c1, Collection<?> c2)
如果两个指定 collection 中没有相同的元素,则返回 true。
2:解决了重复问题那就是合并问题了,既然要合并,而且合并后不能有重复的元素 那就是Set集合 还是在Collections中有这样的工具
Collections.addAll(s1, str); 不过这个方法不爽的地方在于 它不是把集合加到另外一个集合中,而是一个元素一个元素的
添加,那这也难不倒我 那就遍历一下s2集合再取出元素就行了。
文档描述:
public static <T> boolean addAll(Collection<? super T> c,T... elements)
将所有指定元素添加到指定 collection 中。可以分别指定要添加的元素,或者将它们指定为一个数组。
此便捷方法的行为与 c.addAll(Arrays.asList(elements)) 的行为是相同的,
但在大多数实现下,此方法运行起来可能要快得多。
在分别指定元素时,此方法提供了将少数元素添加到现有 collection 中的一个便捷方式:
# Collections.addAll(flavors, "Peaches 'n Plutonium", "Rocky Racoon");
这最后一句描述其实给我们一种新的用法,也就是说如果我要添加的元素不是很多,而且很明确知道他的值得话,可以直接这样使用
Collections.addAll(s1, "string1","string2"); 多个元素中间用逗号隔开就好了
3:由于给定的集合有5个 每个之间要进行重复的比较,这样的比较的工作量是很大的,我不可能去一一用hasSame函数去写,所以考虑
使用循环去遍历 那么问题又归结为如何遍历能是5个元素之间两两之间进行比较呢 比较的元素是set集合,考虑将set集合放入到list集合
使用数组的遍历来实现两两之间的比较 这个问题就很熟悉了 以前遇到过 就是嵌套循环两个for循环就行了。
4:
解决了比较问题,还有一个问题就是输出的时候是输出的合并后的set集合 那么如何处理被合并掉的集合呢 这里考虑使用另外一个集合来先记录
下被合并掉的集合 然后使用 list的方法l.removeAll(l2); 来剔除掉这些集合即可
这里一开始我想在合并的时候直接删除这些集合 是不好实现的 因为你一旦删除 那么势必会影响到这 2个for循环中的l.size()的值
for (int i = 0; i <l.size(); i++)
{
for(int j=i+1;j<l.size();j++)
一旦这个值变了 这2个for循环也就无法实现两两之间的比较了。
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
public class Disjoint
{
public static void main(String[] args)
{
Set<String> str1 =new TreeSet<String>();
str1.add("aaa");
str1.add("bbb");
str1.add("ccc");
Set<String> str2 =new TreeSet<String>();
str2.add("bbb");
str2.add("ddd");
Set<String> str3 =new TreeSet<String>();
str3.add("eee");
str3.add("fff");
Set<String> str4 =new TreeSet<String>();
str4.add("ggg");
Set<String> str5 =new TreeSet<String>();
str5.add("ddd");
str5.add("hhh");
ArrayList<Set<String>> l = new ArrayList<>();
ArrayList<Set<String>> l2 = new ArrayList<>();
l.add(str1);
l.add(str2);
l.add(str3);
l.add(str4);
l.add(str5);
for (int i = 0; i <l.size(); i++)
{
for(int j=i+1;j<l.size();j++)
{
if(new Disjoint().hasSame(l.get(i),l.get(j))==false)
{
new Disjoint().merge(l.get(i), l.get(j));
l2.add(l.get(j));
}
}
}
l.removeAll(l2);
for(Set<String> s:l)
{
System.out .println(s);
}
}
public Boolean hasSame(Set<String> s1,Set<String> s2)
{
return Collections.disjoint(s1, s2);//没有相同元素返回true
}
public Set<String> merge(Set<String> s1,Set<String> s2)
{
for (String str: s2)
{
Collections.addAll(s1, str);
}
return s1;
}
}