给定一组三元组 S,其中对于每个三元组 s \in S,它认为 s[1] >= s[2] >= s[3],其中 s[i] 是三元组 s 的第 i 个元素。对于任何 s,t,v \in S,让函数 F(s,t,v) 生成一个新的三元组: F(s,t,v)=(max{s[1],t[1],v[ 1]},最大{s[2],t[2],v[2]},最大{s[3],t[3],v[3]})。目标:生成集合 T={F(s,t,v) | s,t,v \in S} 有效。
两个例子:
S = [(9,4,3),(8,6,2),(6,6,4)]
T = [(9,4,3),(8,6,2),(6,6,4),(9,6,3),(9,6,4),(8,6,4)]
S = [(9,4,3),(8,6,2),(6,5,4)]
T = [(9,4,3), (9,6,3), b(9,5,4), b(9,6,4), b(8,6,2), b(8,6,4), b(6,5,4)]
下面是一个简单但相对低效的实现,它完成了上述操作。此代码在 O(n^3) 中运行,|S|=n。问题是:如何更有效地实现这一点?这将涉及提出一个有效的数据结构来保存 S 的排序版本。例如,我们可以观察到 F(s,t,v)=s if t[1],v[1] <= s[1 ], t[2],v[2] <= s[2], t[3],v[3] <= s[3]。因此,如果我们选择三元组 s=(x,y,z),那么我们只需要迭代具有 x' <= x 和 y' >= y 和 z' >= 的三元组 (x',y',z') z。注意:在我的应用程序中 |S| 很大,例如 100000 个三元组。
public class TripleGen {
public static void main(String[] args) {
int[][] ds = new int[][]{{9, 4, 3}, {8, 6, 2}, {6, 5, 4}};
List<Triple> l = Triple.toList(ds);
System.out.println(gen(l));
}
public static Set<Tripple> gen(List<Triple> S) {
Set<Triple> T = new HashSet<>();
for (int i = 0; i < S.size(); i++) {
for (int j = i; j < S.size(); j++) {
for (int k = j; k < S.size(); k++) {
int l = Math.max(S.get(i).x, Math.max(S.get(j).x, S.get(k).x));
int w = Math.max(S.get(i).y, Math.max(S.get(j).y, S.get(k).y));
int h = Math.max(S.get(i).z, Math.max(S.get(j).z, S.get(k).z));
T.add(new Triple(l, w, h));
}
}
}
return T;
}
}
public final class Triple {
public final int x;
public final int y;
public final int z;
public Triple(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public static List<Triple> toList(int[][] ds) {
List<Triple> l = new ArrayList<>(ds.length);
for (int[] d : ds)
l.add(new Triple(d[0], d[1], d[2]));
return l;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Triple t = (Triple) o;
return x == t.x &&
y == t.y &&
z == t.z;
}
public int hashCode() {
return Objects.hash(x, y, z);
}
public String toString() {
return "(" + x + "," + y + "," + z+")";
}
}