我担心这不是一个简单的问题。很长一段时间以来我一直在考虑解决这个问题的正确方法,并希望一大堆新脑能更好地了解这个问题 - 让我们来看看它:
数据:
我们在这里使用的是一个包含多个列的csv文件,这个问题的相关内容是:
我们在这里使用的数据中的每个条目都有这些属性的!null值。
示例数据:
SID,UID,query,rawdate,timestamp,timegap,epoc,lengthwords,lengthchars,rank,clickurl
5,142,westchester.gov,2006-03-20 03:55:57,Mon Mar 20 03:55:57 CET 2006,0,1142823357504,1,15,1,http://www.westchestergov.com
10,142,207 ad2d 530,2006-04-08 01:31:14,Sat Apr 08 01:31:14 CEST 2006,10000,1144452674507,3,12,1,http://www.courts.state.ny.us
11,142,vera.org,2006-04-08 08:38:42,Sat Apr 08 08:38:42 CEST 2006,11000,1144478322507,1,8,1,http://www.vera.org
注意:有多个条目对“Epoc”具有相同的值,这是由于用于收集数据的工具
注2:该列表的大小约为700000,只是fyi
目标:匹配具有相同查询的条目对
范围:共享相同UserID的条目
由于数据收集过程中提到的异常,必须考虑以下因素:
如果两个条目共享“Query”和“Epoc”的相同值,则必须检查列表中的以下元素是否符合这些条件,直到下一个条目对其中一个属性具有不同的值。共享相同Query和Epoc值的条目组将被视为-one-entry,因此为了匹配一对,必须找到与“Query”值匹配的另一个条目。由于缺少更好的名称,让我们称一个共享相同Query和Epoc值的组'chain'
现在已经出局了,它变得容易一些,我们可以从中得到3种类型的对合成:
此处的类型1仅表示列表中的两个条目共享“查询”的相同值,但不包含“Epoc”。
所以这总结了 Equal Query Pairs
还有不同查询对的情况,可以描述如下:
在我们匹配相等的查询对之后,有可能存在未与其他条目配对的条目,因为它们的查询不匹配 - 因为这是其中一部分未与另一条目匹配的条目集合称为“不同查询”
此集合的成员必须在不遵循任何标准的情况下进行配对,但链仍然被视为该对的一个条目。
对于一般匹配对,可能没有冗余对 - 单个条目可以是n对中的一部分,但是两个单独的条目只能形成一对。
实施例
以下条目将配对
UID,Query,Epoc,Clickurl
772,Donuts,1141394053510,https://www.dunkindonuts.com/dunkindonuts/en.html
772,Donuts,1141394053510,https://www.dunkindonuts.com/dunkindonuts/en.html
772,Donuts,1141394053510,https://www.dunkindonuts.com/dunkindonuts/en.html
772,raspberry pi,1141394164710,http://www.raspberrypi.org/
772,stackoverflow,1141394274810,http://en.wikipedia.org/wiki/Buffer_overflow
772,stackoverflow,1141394274850,http://www.stackoverflow.com
772,tall women,1141394275921,http://www.tallwomen.org/
772,raspberry pi,1141394277991,http://www.raspberrypi.org/
772,Donuts,114139427999,http://de.wikipedia.org/wiki/Donut
772,stackoverflow,1141394279999,http://www.stackoverflow.com
772,something,1141399299991,http:/something.else/something/
在这个例子中,甜甜圈是一个链,因此对是(没有标题的亚麻):
My -failed-解决问题的方法:
我为解决这个问题而开发的算法如下:
迭代条目列表,直到UserID的值发生变化。
然后,应用于一个单独的列表,该列表仅包含共享相同UserID的刚刚迭代的元素:
for (int i = 0; i < list.size(); i++) {
Entry tempI = list.get(i);
Boolean iMatched = false;
//boolean to save whether or not c1 is set
Boolean c1done = false;
Boolean c2done = false;
//Hashsets holding the clickurl values of the entries that form a pair
HashSet<String> c1 = null;
HashSet<String> c2 = null;
for (int j = i + 1; j < list.size(); j++) {
Entry tempJ = list.get(j);
// Queries match
if (tempI.getQuery().equals(tempJ.getQuery())) {
// wheter or not Entry at position i has been matched or not
if (!iMatched) {
iMatched = true;
}
HashSet<String> e1 = new HashSet<String>();
HashSet<String> e2 = new HashSet<String>();
int k = 0;
// Times match
HashSet<String> chainset = new HashSet<String>();
if (tempI.getEpoc() == tempJ.getEpoc()) {
chainset.add(tempI.getClickurl());
chainset.add(tempJ.getClickurl());
} else {
e1.add(tempI.getClickurl());
if (c1 == null) {
c1 = e1;
c1done = true;
} else {
if (c2 == null) {
c2 = e1;
c2done = true;
}
}
}
//check how far the chain goes and get their entries
if ((j + 1) < list.size()) {
Entry tempjj = list.get(j + 1);
if (tempjj.getEpoc() == tempJ.getEpoc()) {
k = j + 1;
//search for the end of the chain
while ((k < list.size())
&& (tempJ.getQuery().equals(list.get(k)
.getQuery()))
&& (tempJ.getEpoc() == list.get(k).getEpoc())) {
chainset.add(tempJ.getClickurl());
chainset.add(list.get(k).getClickurl());
k++;
}
j = k + 1; //continue the iteration at the end of the chain
if (c1 == null) {
c1 = chainset;
c1done = true;
} else {
if (c2 == null) {
c2 = chainset;
c2done = true;
}
}
// Times don't match
}
} else {
e2.add(tempJ.getClickurl());
if (c1 == null) {
c1 = e2;
c1done = true;
} else {
if (c2 == null) {
c2 = e2;
c2done = true;
}
}
}
/** Block that compares the clicks in the Hashsets and computes the resulting data
* left out for now to not make this any more complicated than it already is
**/
// Queries don't match
} else {
if (!dq.contains(tempJ)) { //note: dq is an ArrayList holding the entries of the differen query set
dq.add(tempJ);
}
}
if (j == al.size() - 1) {
if (!iMatched) {
dq.add(tempI);
}
}
}
if (dq.size() >= 2) {
for (int z = 0; z < dq.size() - 1; z++) {
if (dq.get(z + 1) != null) {
/** Filler, iterate dq just like the normal list with two loops
*
**/
}
}
}
}
所以,使用过多的循环我会尝试匹配这些对,导致一个非常长的运行时间到目前为止我还没有看到
好的,我希望我没有忘记任何重要的事情,我稍后会添加更多所需的信息 如果你已经做到这一点,感谢阅读 - 希望你有一个可能对我有帮助的想法
答案 0 :(得分:1)
使用SQL将数据导入数据库,然后执行查询。你的txt文件太大了;难怪通过它需要很长时间。 :)
答案 1 :(得分:0)
首先,从每个链中删除除一个条目以外的所有条目。为此,请按(userid,query,epoch)排序,删除重复项。
然后,扫描已排序的列表。获取(userid,query)对的所有条目。如果只有一个,将其保存在列表中以供以后处理,否则发出所有对。
对于您保存以供以后处理的给定用户的所有条目(这些是类型2和3),发出对。