如果连续两次出现相同的值,则减少数组长度

时间:2017-10-30 19:10:03

标签: c breadth-first-search

我有两个阵列,其中包含x& y坐标,它们是整数。

现在我想减少数组,以便

arrayX[5] = 100 //first occurance of this value
arrayX[6] = 100 //same
arrayX[7] = 100 //same
arrayX[8] = 100 //same
arrayX[9] = 125 //NEW VALUE! Most likely a turn

,而

arrayY[5] = 350 //will be kept due to first entry of this coordinate
arrayY[6] = 375 //will be removed due to X
arrayY[7] = 400 //will be removed due to X
arrayY[8] = 425 //will be removed due to X
arrayY[9] = 450 //Then we proceed to look ahead from here

输出应为:

(ArrayX[5] = 100, ArrayY[5] = 350)
(ArrayX[8] = 100, ArrayY[8] = 425)
//ArrayX[6] -> ArrayX[7] Will now have been deleted
//proceed to look ahead for new redundant values

只有一个条目进入数组,其中坐标是多余的。

截至目前:我的数组看起来像这样(LIFO):

(X: 450.000000, Y: 300.000000) //Last pos
(X: 425.000000, Y: 300.000000)
(X: 400.000000, Y: 300.000000)
(X: 375.000000, Y: 300.000000)
(X: 350.000000, Y: 300.000000)
(X: 325.000000, Y: 300.000000)
(X: 300.000000, Y: 300.000000)
(X: 275.000000, Y: 300.000000)
(X: 250.000000, Y: 300.000000)
(X: 225.000000, Y: 300.000000)
(X: 200.000000, Y: 300.000000)
(X: 175.000000, Y: 300.000000)
(X: 150.000000, Y: 300.000000)
(X: 125.000000, Y: 300.000000) //First pos

如您所见,关于如何到达目标坐标有很多冗余坐标。

我们只想检查转弯发生的位置(新的价值对条目)以及开始和结束坐标。

(有关此内容的进一步直观说明,请参见下文)

所需的减少数组(在这种情况下):

(X: 450.000000, Y: 300.000000) //Last pos
(X: 125.000000, Y: 300.000000) //First pos
//all repeating nodes have been removed from the array

图形说明●=达到目标的最快方式(数组( x,y ):

点(●)是我们的数组,以视觉方式表示。由于我们的数组包含如上所述的坐标。 X,Y导致●出现在那个地方

@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@  
@@@  !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !  @@@
@@@  !   !                                                                           !   !  @@@
@@@  !   !                                                                           !   !  @@@
@@@  !   !                                   14  S   14                              !   !  @@@
@@@  !   !                               14  13  ●   13  14                          !   !  @@@
@@@  !   !                           14  13  12  ●   12  13  14                      !   !  @@@
@@@  !   !                       14  13  12  11  ●   11  12  13  14                  !   !  @@@
@@@  !   !                   14  13  12  11  10  ●   10  11  12  13  14              !   !  @@@
@@@  !   !               14  13  12  11  10   9  ●    9  10  11  12  13  14          !   !  @@@
@@@  !   !           14  13  12  11  10   9   8  ●    8   9  10  11  12  13  14      !   !  @@@
@@@  !   !       14  13  12  11  10   9   8   7  ●    7   8   9  10  11  12  13  14  !   !  @@@
@@@  !   !   14  13  12  11  10   9   8   7   6  ●    6   7   8   9  10  11  12  13  !   !  @@@
@@@  !   !   13  12  11  10   9   8   7   6   5  ●    5   6   7   8   9  10  11  12  !   !  @@@
@@@  !   !   12  11  10   9   8   7   6   5   4  ●    4   5   6   7   8   9  10  11  !   !  @@@
@@@  !   !   11  10   9   8   7   6   5   4   3  ●    3   4   5   6   7   8   9  10  !   !  @@@
@@@  !   !   10   9   8   7   6   5   4   3   2  ●    2   3   4   5   6   7   8   9  !   !  @@@
@@@  !   !    9   8   7   6   5   4   3   2   1  G    1   2   3   4   5   6   7   8  !   !  @@@
@@@  !   !   10   9   8   7   6   5   4   3   2   1   2   3   4   5   6   7   8   9  !   !  @@@
@@@  !   !   11  10   9   8   7   6   5   4   3   2   3   4   5   6   7   8   9  10  !   !  @@@
@@@  !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !  @@@
@@@  !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !  @@@
@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@

使用数组缩减:

@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@  
@@@  !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !  @@@
@@@  !   !                                                                           !   !  @@@
@@@  !   !                                                                           !   !  @@@
@@@  !   !                                   14  S   14                              !   !  @@@
@@@  !   !                               14  13  ●  13  14                          !   !  @@@
@@@  !   !                           14  13  12  11   12  13  14                      !   !  @@@
@@@  !   !                       14  13  12  11  10   11  12  13  14                  !   !  @@@
@@@  !   !                   14  13  12  11  10  9   10  11  12  13  14              !   !  @@@
@@@  !   !               14  13  12  11  10   9  8    9  10  11  12  13  14          !   !  @@@
@@@  !   !           14  13  12  11  10   9   8  7    8   9  10  11  12  13  14      !   !  @@@
@@@  !   !       14  13  12  11  10   9   8   7  6    7   8   9  10  11  12  13  14  !   !  @@@
@@@  !   !   14  13  12  11  10   9   8   7   6  5    6   7   8   9  10  11  12  13  !   !  @@@
@@@  !   !   13  12  11  10   9   8   7   6   5  4    5   6   7   8   9  10  11  12  !   !  @@@
@@@  !   !   12  11  10   9   8   7   6   5   4  3    4   5   6   7   8   9  10  11  !   !  @@@
@@@  !   !   11  10   9   8   7   6   5   4   3  2    3   4   5   6   7   8   9  10  !   !  @@@
@@@  !   !   10   9   8   7   6   5   4   3   2  ●    2   3   4   5   6   7   8   9  !   !  @@@
@@@  !   !    9   8   7   6   5   4   3   2   1  G    1   2   3   4   5   6   7   8  !   !  @@@
@@@  !   !   10   9   8   7   6   5   4   3   2   1   2   3   4   5   6   7   8   9  !   !  @@@
@@@  !   !   11  10   9   8   7   6   5   4   3   2   3   4   5   6   7   8   9  10  !   !  @@@
@@@  !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !  @@@
@@@  !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !   !  @@@
@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@

阵列减少的例外情况是我们遇到这样一个转折点:

●
●
●
●
● ● ● ● ●

应该减少到:

●



●       ●

当前代码:

当找到目标节点时,计数器会递增,坐标将存储在该阵列计数器位置。

  double arrayX[counter]; //this is where the coordinates are stored
  double arrayY[counter]; // -||- 

  //My attempt at reduction
  for(int i=counter; i > 0; i--){ //checking array
    for(int j=i;j < counter;j++){ 
        if(arrayY[counter] != arrayY[counter+2] && arrayX[counter] != arrayX[counter+2]){ //IF x != x+2 that means we have a new value at x+1
          arrayY[counter] =  arrayY[counter+1];
          arrayX[counter] =  arrayX[counter+1];
          counter--;
        }
    }
  }

然而,这只能得到第一对,然后是其他地方的0。

由于我在APK环境中工作,因此任何其他代码都可能无关紧要。上面的代码是两个需要根据它们的值进行缩减的数组。 函数代码生成路径(片段):

    while(maxValue  != MAP_GOAL){                      //while we are not at the goal
      n1             = GetCellState(grid,bestCell.i,bestCell.j-1); 
      n2             = GetCellState(grid,bestCell.i,bestCell.j+1);
      n3             = GetCellState(grid,bestCell.i-1,bestCell.j);
      n4             = GetCellState(grid,bestCell.i+1,bestCell.j);
      if((n1 < maxValue) && (n1 >= 0)){
          maxValue   = n1;
          nextCell.i = bestCell.i;
          nextCell.j = bestCell.j-1;
      }
      if((n2 < maxValue) && (n2 >= 0)){
          maxValue   = n2;
          nextCell.i = bestCell.i;
          nextCell.j = bestCell.j+1;
      }
      if((n3 < maxValue) && (n3 >= 0)){
          maxValue   = n3;
          nextCell.i = bestCell.i-1;
          nextCell.j = bestCell.j;
      }
      if((n4 < maxValue) && (n4 >= 0)){
          maxValue   = n4;
          nextCell.i = bestCell.i+1;
          nextCell.j = bestCell.j;

      }
        Push           (Path,nextCell);
        bestCell.i   = nextCell.i;
        bestCell.j   = nextCell.j;
        bestCell.h_value = 0;
        ChangeCellState(grid,bestCell.i,bestCell.j,-9); // mark path with custom sign
        counter++;

    }                                                   //end while
  }else{
    printf("\nPath was NOT found, terminating...");
    exit(1);
  }                                                    // end if-else

  printf("\nPath FOUND!\n");
  //expanding the cells

  double arrayX[counter];
  double arrayY[counter];
   /////////////////////////////////////////////////////////////
   //          THIS IS WHERE THE REDUCTION SHOULD TAKE PLACE  //
   /////////////////////////////////////////////////////////////
Cell temp;
  for(int i=0; i < counter; i++){
    temp      = Pop(Path);
    arrayX[i] = temp.i * CELLSIZE;
    arrayY[i] = temp.j * CELLSIZE;
  }

  for(int i=0;i < (sizeof(arrayX) / sizeof(arrayX[0])); i++){
    printf("(X: %f, Y: %f) \n",arrayX[i], arrayY[i]);
  }

TL; DR - 如果其中一个数组有多个具有相同值的条目,我将如何减少链接到彼此的数组对。

2 个答案:

答案 0 :(得分:1)

也许我在这里遗漏了一些东西,但是你无法使用常规技术来过滤数组:

// given: array a[n] of length n

int k = 0;

for (int i = 0; i < n; i++) {
    if (keep(a[i]) a[k++] = a[i];
}

// k is the new array length

在您的情况下,您必须保留第一个和最后一个元素,您还需要向后退一步,领先一步。以下函数压缩点坐标数组。该数组最初的大小为n;可能减小的大小从函数中返回:

struct point {
    int x, y;
};

int compact_points(struct point pt[], int n)
{
    int k = 1;                     // keep the first point

    if (n < 3) return n;

    for (int i = 1; i < n - 1; i++) {
        int x = pt[i].x;
        int y = pt[i].y;

        // skip middle points of three equal x or y coords
        if (x == pt[k - 1].x && x == pt[i + 1].x) continue;
        if (y == pt[k - 1].y && y == pt[i + 1].y) continue;

        // copy corner points
        pt[k++] = pt[i];
    }

    pt[k++] = pt[n - 1];           // add last point

    return k;
}

该代码使用结构,但它很容易修改它以便它使用两个数组:

int compact_arrays(int *x, int *y, int n)
{
    int k = 1;

    if (n < 3) return n;

    for (int i = 1; i < n - 1; i++) {
        if (x[i] == x[k - 1] && x[i] == x[i + 1]) continue;
        if (y[i] == y[k - 1] && y[i] == y[i + 1]) continue;

        x[k] = x[i];
        y[k] = y[i];
        k++;
    }

    x[k] = x[n - 1];
    y[k] = y[n - 1];

    return k + 1;
}

确保保留返回值,因为它是新的数组大小:

int main(void)
{
    int x[14] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 4, 5, 5, 5, 5 };
    int y[14] = { 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 3, 4 };
    int n = 14;

    for (int i = 0; i < n; i++) printf("%d, %d\n", x[i], y[i]);
    puts("");

    n = compact_arrays(x, y, 14);

    for (int i = 0; i < n; i++) printf("%d, %d\n", x[i], y[i]);
    puts("");

    return 0;
}

您也可以在对数组进行压缩时压缩数组:当数组有多个元素且您添加的x或y值等于数组中最后两个元素的x或y值时,覆盖数组最后一个元素否则,追加到数组:

enum {
    arrayMax = 20
};    

struct array {
    int n;
    int x[arrayMax];
    int y[arrayMax];
};

void array_append(struct array *a, int x, int y)
{
    if (a->n > 1) {
        int n1 = a->n - 1;
        int n2 = n1 - 1;

        if ((x == a->x[n1] && x == a->x[n2])
         || (y == a->y[n1] && y == a->y[n2]))
        {
            a->x[n1] = x;
            a->y[n1] = y;
            return;
        }
    }

    if (a->n < arrayMax) {
        a->x[a->n] = x;
        a->y[a->n] = y;
        a->n++;
    }
}

int main(void)
{
    int x[14] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 4, 5, 5, 5, 5 };
    int y[14] = { 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 3, 4 };
    struct array a = {0};

    for (int i = 0; i < 14; i++) {
        array_append(&a, x[i], y[i]);
    }

    for (int i = 0; i < a.n; i++) printf("%d, %d\n", a.x[i], a.y[i]);
    puts("");

    return 0;
}

答案 1 :(得分:1)

您可以在一个循环中完成此操作。

//x = [100,100,100,100,125]
//y = [350,375,400,425,450]

int z = 0;
for (int i = 0; i < n; i++) {
  if (i == n - 1 || z == 0 || (x[i] != x[i + 1] || x[i] != x[z - 1]) && (y[i] != y[i + 1] || y[i] != y[z - 1])) {
      x[z] = x[i];
      y[z] = y[i];
      z++;
  }
}

这应该给你:

//x = [100, 100, 125, 100, 125]
//y = [350, 425, 450, 425, 450]
//z = 3

现在只需删除索引&gt; = z的其余元素,这样就可以了:

//x = [100, 100, 125]
//y = [350, 425, 450]