java 集合试题

给定一个字符串的集合,格式如: 
{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;
		
	}
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java集合Java编程语言提供的一种数据结构,可以用于存储和操作一组相关的对象。Java提供了许多集合类,包括List、Set和Map等。 List是一种有序的集合,可以根据索引来访问元素。常用的List实现类有ArrayList和LinkedList。ArrayList是基于数组实现的,支持快速随机访问,但插入和删除元素的效率较低;LinkedList是基于链表实现的,支持快速插入和删除元素,但访问元素的效率较低。 Set是一种不允许重复元素的集合。常用的Set实现类有HashSet和TreeSet。HashSet是基于哈希表实现的,不保证元素的顺序,但插入和查询的效率较高;TreeSet是基于红黑树实现的,保证元素按照一定的顺序排列,插入和查询的效率较低。 Map是一种键值对的集合,每个键值对称为一个Entry。常用的Map实现类有HashMap和TreeMap。HashMap是基于哈希表实现的,不保证键值对的顺序,但插入和查询的效率较高;TreeMap是基于红黑树实现的,保证键值对按照键的顺序排列,插入和查询的效率较低。 Java集合提供了许多操作方法,如添加元素、删除元素、查找元素、遍历集合等。可以使用foreach循环或迭代器来遍历集合中的元素。集合类还提供了一些便捷的方法,如排序、过滤、映射等,可以方便地对集合中的元素进行操作。 总的来说,Java集合Java编程语言提供的一种方便且高效的数据结构。根据不同的需求可以选择适合的集合类,通过简单的方法调用就可以完成许多常见的操作。因此,在编写Java程序时,合理地使用集合可以提高代码的可读性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值