鉴于我有以下结矢量U1, U2, U3
U1 = {0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 0.8};
U2 = {0.21, 0.25, 0.3, 0.6, 0.7, 0.8};
U3 = {0.25, 0.3, 0.7, 0.8};
现在我想计算他们的 常见结矢量 ,即包含U1, U2, U3
所有元素并且长度最小的结矢量。例如,包含U1
的所有元素意味着包含
{0.25, 0.25, 0.5, 0.5, 0.75, 0.75, 0.8}
,而不是{0.25, 0.5, 0.75, 0.8}
。
对于这种情况,U1, U2, U3
的公共结矢量是:
commonKnotsVector = {0.21, 0.25, 0.25, 0.3, 0.5, 0.5, 0.6, 0.7, 0.75, 0.75, 0.8}
对于 common knots vector ,我的 Mathematica 算法如下所示:
commonKnotsVector[knots_] :=
Module[{step1, step2, step3, step4},
step1 = SortBy[Join @@ Tally /@ knots, First];
step2 = GatherBy[step1, First];
step3 = Last /@ (SortBy[#, Last] & /@ step2);
step4 = step3 /. {x_, n_} :> ConstantArray[x, n];
Flatten[step4]
]
commonKnotsVector[{U1, U2, U3}]
(*{0.21, 0.25, 0.25, 0.3, 0.5, 0.5, 0.6, 0.7, 0.75, 0.75, 0.8}*)
答案 0 :(得分:2)
您提到了merge
代码 - 这是正确的方法,使用基于merge sort的三向merge
步骤的algortihm。
你有三个排序的矢量。伪代码:
While vectors are not empty:
Find the smallest element among the heads of all vectors
Extract it into `current` element
Add `current` to output vector
Until next smallest element is equal to `current`:
Just remove it from vector head.
您可以使用基于二进制堆的最简单优先级队列 - 此处堆只包含三个元素。
答案 1 :(得分:0)
使用以下算法
i j k min_val
1 1 1 0.21 j++
1 2 1 0.25 i++ j++ k++
2 3 2 0.25 i++
3 3 2 0.3 j++ k++
3 4 3 0.5 i++
4 4 3 0.5 i++
5 4 3 0.6 j++
5 5 3 0.7 j++ k++
5 6 4 0.75 i++
6 6 4 0.75 i++
7 6 4 0.8 i++ j++ k++
//===>common vector
U = {0.21, 0.25, 0.25, 0.3, 0.5, 0.5, 0.6, 0.7, 0.75, 0.75, 0.8}
#define min_two(a, b) (a) > (b) ? (b) :(a)
//count denotes the length of common vector of U1, U2
int two_vec_common(double *U1, double *U2, int len1, int len2, double *temp) {
int i, j;
double min_val;
int count = 0;
i = j = 0;
while (i < len1 || j < len2) {
min_val = min_two(U1[i], U2[j]);
temp[count++] = min_val;
if(U1[i] == min_val) i++;
if(U2[j] == min_val) j++;
}
return count;
}
double min_three(double x, double y, double z) {
if (x <= y && x <= z) return x;
if (y <= x && y <= z) return y;
if (z <= x && z <= y) return z;
}
/*count denotes the length of common vector of U1, U2, U3
len1, len2, len3 denote the length of vector U1, U2, U3, respectively
the pointer variable temp stores the values of common vector*/
int three_vec_common(double *U1, double *U2, double *U3, int len1, int len2, int len3, double *temp) {
int i, j, k;
double min_val;
int count = 0;
i = j = k = 0;
while (i < len1 || j < len2 || k < len3) {
min_val = min_three(U1[i], U2[j], U3[k]);
temp[count++] = min_val;
if(U1[i] == min_val) i++;
if(U2[j] == min_val) j++;
if(U3[k] == min_val) k++;
}
return count;
}