0

我有一个超过 2 列的表(比如说 A、B 和 C)。一列包含一些数字(C),我想做一个“分组”,比如分组,对C中的数字求和,但我不知道这样做的算法。

我尝试按每一列对表格进行排序(从最后一个到第一个,除了数字列(C),所以在这种情况下:排序(B)然后排序(A)),然后,只要n行在A中包含相同的值和 B 在n-1第 行中,我将第 1 行的数字添加nn-1第 1 行(在 C 列中),然后删除第nth 行。否则,如果行中的 A 或 B 值与行n中的 A 或 B 值不同n-1,我将移至下一行。然后我重复算法直到表中的最后一行。但不知何故,这并不是一直有效,特别是当有更多列时(有些行仍未分组,可能是因为排序方法)。

我想知道这是否是一个好的分组算法,我需要在排序方法中寻找问题,或者我需要使用另一种(排序和/或分组)算法以及哪个算法。谢谢你。

LE:显然,在彻底检查了代码并修复了像我这样的初级程序员经常犯的一些小错误之后,我使用的算法运行良好 :)

4

2 回答 2

2

我认为这样做的一个好方法是将您的行包装到一个类中,实现 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);
于 2012-09-20T12:39:57.610 回答
0

我认为关于 group by 应该考虑三件事

  1. 小于或等于是抽象
    比较两行A,B根据它的列(C1..Cn)是这样的:比较从C1到Cn的每一列,如果我们能得到哪个小于,则返回,或者如果两个值相等,然后我们去比较下一个,重复这个直到返回。

  2. 我们选择哪种算法
    1)建立一个二叉搜索树或哈希表来存储元组,当我们得到一个元组时,搜索相等的元组,如果有,则合并具有相同组值的元组,否则将其放入我们的搜索结构
    2)读取一些元组,然后排序,遍历缓冲区并合并我更喜欢 1 而不是 2 的同一组。

  3. 内存大小
    如果输出输入很大,我们必须考虑内存限制。我们可以使用合并算法来处理这个问题。如果内存超过了我们的限制,那么当我们读完输入时,将内存中的元组按组列顺序写入磁带,然后将结果集合并到磁带中。

于 2013-12-07T02:50:25.310 回答