合并结矢量以获得常见的结矢量

时间:2016-08-22 03:16:42

标签: c algorithm merge

鉴于我有以下结矢量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 算法如下所示:

enter image description here

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}*)

问题

  • 现在我想知道如何在C中处理这个问题?我不知道C算法。

2 个答案:

答案 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} 

两个向量的C函数

#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;
}

三个向量的C函数

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;
}