分组功能算法求教

weixin_41086105 2019-03-07 09:26:58
分组逻辑为:

当原则日期和时间后,分组规则以ip1,ip2,mac进行分组,这三个项中任意一个相同则被分为一组。甲和乙的ip1相同,因此甲和乙一组,而乙和丙的ip2相同,因此甲乙丙被分为一组,而丁的ip2和戊的ip2相同他俩被分为一组,最后由于戊的mac和乙的mac相同,因此 甲乙丙丁戊他们形成了一组。
这里有几点需要注意
1.实际上分组条件不是3种,而是30多种,且可自由组合搭配
2.对于甲来说,如果甲在一个时段内,ip1不同,同时ip1作为分组条件,则参与分组的数据中会有两个甲和其它进行匹配,匹配后会并为一组
3.无法在数据库中固化实现,因为时间日期区域作为可变条件,所以只能在程序中实现
4.时间复杂度尽可能高,必要时可用空间换时间
...全文
629 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_41086105 2019-03-11
  • 打赏
  • 举报
回复
首先感谢,这个问题我昨天给您回复完之后已经发现了。参与计算的数据量真的小不了,实际上是千万级别的数据。不知道有没有空间换时间的算法(如果空间不因为数据量崩掉的话)
nayi_224 2019-03-11
  • 打赏
  • 举报
回复
报错与算法无关,是我犯了一个很基础的错误。改成这样
					for(int l = merge.size() - 1; l >= 1; l--){
						clu.remove(Integer.valueOf(merge.get(l)).intValue());
					}
这个算法本身与地图中的点聚合算法非常像,你可以查一下相关算法。 复杂度应该是n2,直接跑100W数据是不可能的。我是觉得想办法削减数据量要比找其他算法更容易些。
翩惊鸿 2019-03-10
  • 打赏
  • 举报
回复
就套循环呗,用栈,队列,先比较时间,递归,从底往顶比较时间相同全出栈进队列,然后再通过递归和栈内剩下的比较,然后再进队列呗。
weixin_41086105 2019-03-10
  • 打赏
  • 举报
回复
您的这个算法优点问题,
Bean b1 = new Bean(1, 1, 1, 2, 3);
Bean b2 = new Bean(2, 1, 3, 21, 31);
Bean b3 = new Bean(3, 1, 11, 2, 33);
Bean b4 = new Bean(4, 1, 1, 222, 3333);
Bean b5 = new Bean(5, 1, 14, 24, 31);
Bean b6 = new Bean(6, 1, 3, 1211, 33);
的时候会报错
或者在
Bean b1 = new Bean(1, 1, 1, 2, 3);
Bean b2 = new Bean(2, 1, 3, 21, 31);
Bean b3 = new Bean(3, 1, 11, 2, 33);
Bean b4 = new Bean(4, 1, 1, 222, 3333);
Bean b5 = new Bean(5, 1, 14, 24, 31);
Bean b6 = new Bean(5, 1, 1, 1211, 44);

static class Bean{
public int name;
public int time;

public int ip1;
public int ip2;
public int ip3;

public Bean(int name, int time, int ip1, int ip2, int ip3) {
super();
this.name = name;
this.time = time;
this.ip1 = ip1;
this.ip2 = ip2;
this.ip3 = ip3;
}

public boolean compare(Bean that){
if(this.ip1 == that.ip1 || this.ip2 == that.ip2 || this.ip3 == that.ip3
|| this.name == that.name)
return true;
else
return false;
}

public String toString() {
// TODO Auto-generated method stub
return this.name + "";
}

}
也会报错。报错的位置是remove的时候,由于这个算法我还没有看明白,所以请教一下,是不是哪里您没有考虑到
weixin_41086105 2019-03-08
  • 打赏
  • 举报
回复
哎,就是数据量降不了才不知道该怎么办啊
问一下: bigList中有很多数据

while(bigList.size() != 0) {
list = new ArrayList<String>()
list.add(bigList.get(0));
list.remove(0);
for (long i = 0; i < bigList.size(); i++) {
tem = list.get(i)
for(long j = 0; j < list.size(); i++) {
if (tem.getSomething().equals(list.get(i).getSomething())) {
list.add(list.get(i));
bigList.remove(i)
i = -1;
}
}
}
}
这个时间复杂度能帮我算一下吗?
nayi_224 2019-03-07
  • 打赏
  • 举报
回复
六度空间。。。不过我是仿造聚合算法写的。 第二点没看懂,先按时间完全一致考虑
package test.gt70;

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

public class Test78 {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<Bean> src = new ArrayList();
		Bean b1 = new Bean(1, 1, 1, 2, 3);
		Bean b2 = new Bean(2, 1, 3, 21, 31);
		Bean b3 = new Bean(3, 1, 11, 2, 33);
		Bean b4 = new Bean(4, 1, 1, 222, 3333);
		Bean b5 = new Bean(5, 1, 14, 24, 31);
		src.add(b1);
		src.add(b2);
		src.add(b3);
		src.add(b4);
		src.add(b5);
		
		List<Set<Bean>> clu = new ArrayList();
		
		for(int i = 0; i < src.size(); i++){
			if(clu.size() == 0){
				Set<Bean> tempSet = new HashSet();
				tempSet.add(src.get(i));
				clu.add(tempSet);
			}else {
				
				List<Integer> merge = new ArrayList();
				for(int j = 0; j < clu.size(); j++){
					
					for(Bean tempBean: clu.get(j)){
						if(src.get(i).compare(tempBean)){
							merge.add(j);
							break;
						}
					}
					
				}
				
				if(merge.size() == 0){
					Set<Bean> tempSet = new HashSet();
					tempSet.add(src.get(i));
					clu.add(tempSet);
				}else if(merge.size() == 1){
					clu.get(merge.get(0)).add(src.get(i));
				}else {
					for(int k = 1; k < merge.size(); k++){
						clu.get(merge.get(0)).addAll(clu.get(merge.get(k)));
					}
					for(int l = merge.size(); l > 1; l--){
						clu.remove(merge.get(l));
					}
				}
			}
		}
		
		System.out.println(clu);
	}
	
	static class Bean{
		public int name;
		public int time;
		
		public int ip1;
		public int ip2;
		public int ip3;
		
		public Bean(int name, int time, int ip1, int ip2, int ip3) {
			super();
			this.name = name;
			this.time = time;
			this.ip1 = ip1;
			this.ip2 = ip2;
			this.ip3 = ip3;
		}
		
		public boolean compare(Bean that){
			if(this.ip1 == that.ip1 || this.ip2 == that.ip2 || this.ip3 == that.ip3)
				return true;
			else
				return false;
		}
		
		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return this.name + "";
		}
		
	}

}
nayi_224 2019-03-07
  • 打赏
  • 举报
回复
引用 2 楼 weixin_41086105 的回复:
@nayi_224,首先感谢您的解答,时间维度不用考虑,我说第二点是指同一个人在分组的时候可能出现两次,因为在提取数据的时候假设Bean b1 = new Bean(1, 1, 1, 2, 3); 同时Bean b2 = new Bean(2, 1, 1, 2, 3); 而这两条数据都属于甲,而他们的第一列不一致,出现这种情况是因为,甲使用了不同的设备,因此可以能出现两条。最后要合并的意思是指 这两个甲在分组之后(假设只以第一列进行分组),甲必然会出现在两个组里,而由于他们都是甲,因此最后带有甲的组要进行合并。 看了一下您的算法,感觉时间复杂度有些高,毕竟数据量百万级别。不知道您还能不能在优化一下呢,谢谢
你是指有两个甲,并且把它们算作一组?改一下compare方法就行 if((this.ip1 == that.ip1 || this.ip2 == that.ip2 || this.ip3 == that.ip3) || this.name == that.name) 优化方面,小优化的余地应该是有的,但是100W的数据,用这样的算法,怎么优化都没用,除非再找一个别的算法。 先想办法把数据量降低一下吧,比如把全部甲的数据合并成一条,甚至把多个人的数据合并成一条,然后在判断上下点功夫。最好把数据量降低到万级。
weixin_41086105 2019-03-07
  • 打赏
  • 举报
回复
修正一下,前面写的是时间复杂度尽可能高是错的,应该是时间复杂度尽可能低,谢谢大家了
weixin_41086105 2019-03-07
  • 打赏
  • 举报
回复
@nayi_224,首先感谢您的解答,时间维度不用考虑,我说第二点是指同一个人在分组的时候可能出现两次,因为在提取数据的时候假设Bean b1 = new Bean(1, 1, 1, 2, 3); 同时Bean b2 = new Bean(2, 1, 1, 2, 3); 而这两条数据都属于甲,而他们的第一列不一致,出现这种情况是因为,甲使用了不同的设备,因此可以能出现两条。最后要合并的意思是指 这两个甲在分组之后(假设只以第一列进行分组),甲必然会出现在两个组里,而由于他们都是甲,因此最后带有甲的组要进行合并。

看了一下您的算法,感觉时间复杂度有些高,毕竟数据量百万级别。不知道您还能不能在优化一下呢,谢谢

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧