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

Reduce array-length if same value occurs twice in a row

我有两个数组,其中填充了 x 和 y 坐标,它们是整数。

现在我想减少数组,这样 if

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

数组中只有一个条目是坐标冗余的。

截至目前:我的数组如下所示(后进先出):

(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 - 当其中一个数组具有多个相同值的条目时,我如何减少彼此链接的数组对。

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

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

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

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

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

//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

现在只需删除 indices >= z 的其余元素即可:

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