我有一个超过2列的表(比方说A、B和C)。一列包含一些数字( C ),我想做一个类似分组的"group by“,将C中的数字相加,但我不知道这样做的算法。
我尝试按每一列对表进行排序(从最后到第一,除了numbers列(C),因此在本例中: sort(B),然后sort(A)),然后,只要nth行包含与n-1th行相同的A和B中的值,我就将nth行到n-1th行(在C列中)的数字相加,然后删除nth行。否则,如果行n中的A或B值与第n-1行中的A或B值不同,我将直接移动到下一行。然后我重复这个算法,直到表中的最后一行。但不知何故,这并不总是有效的,特别是当有更多的列时(一些行仍然没有分组,可能是由于排序方法的原因)。
我想知道这是不是一个好的分组算法,我需要在排序方法中寻找问题,或者我需要使用另一个(排序和/或分组)算法以及哪一个。谢谢。
LE:显然,我使用的算法在彻底检查代码并修复了像我这样的初级程序员经常犯的一些小错误之后工作得很好:)
发布于 2012-09-20 20:39:58
我认为这样做的一个好方法是将行包装到一个类中,实现equals方法,然后使用Map将值相加:
public class MyRow {
private Long columnA;
private String columnB;
private int columnC;
@Override
public boolean equals(final Object other) {
if (!other instanceof MyRow) {
return false;
}
final MyRow otherRow = (MyRow) other;
return this.columnA.equals(otherRow.getColumnA()) && this.columnB.equals(otherRow.getColumnB);
}
}然后,您可以遍历所有行,并创建一个Map来保存C的和。
final Map<MyRow, Integer> computedCSums = new HashMap<MyRow, Integer>();
for (final MyRow myRow : myRows) {
if (computedCSums.get(myRow) == null) {
computedCSums.put(myRow, myRow.getColumnC());
} else {
computedCSums.put(myRow, computedSums.get(myRow) + myRow.getColumnC());
}
}然后,要获得任何行的分组C的总和,只需执行以下操作:
computedCSum.get(mySelectedRow);发布于 2013-12-07 10:50:25
我认为关于group by应该考虑三件事
根据列(C1..Cn)比较两行A、B如下所示:比较从C1到Cn的每一列,如果我们可以得到较小的值,则返回,或者如果两个值相等,则转到下一步比较,重复此操作,直到返回。
1)建立二叉树或哈希表来存储元组,当得到元组时,搜索相等的元组,如果有,则合并具有相同组值的元组,否则将其放入我们的搜索结构中
2)读取一些元组,然后排序,遍历缓冲区并合并相同的组我更喜欢1而不是2。
如果输出输入很大,我们必须考虑内存限制。我们可以使用合并算法来处理这个问题。如果内存超出了我们的限制,那么当我们完成读取输入时,将内存中的元组按它们的组列的顺序写入磁带,然后将结果集合并到磁带中。
https://stackoverflow.com/questions/12512171
复制相似问题