如何在二维数组中找到两个给定位置之间的中间位置

huangapple go评论64阅读模式
英文:

How to find the middle position between two given position in a 2D array

问题

我有一个二维数组,我想要找到两个给定位置之间的中间位置:下面的示例显示了每个位置的索引。

00,01,02,03
10,11,12,13
20,21,22,23
30,31,32,33

输入:

  • 对于位置 2333,我应该得到输出位置 31
    这里的输入是 iStart 为 2,jStart 为 3,同样 iEnd 为 3,jEnd 为 3
    期望的输出是 i_mid = 3 和 j_mid = 1

  • 对于位置 0022,我应该得到输出位置 11
    这里的输入是 iStart 和 jStart 都为 0,同样 iEnd 和 jEnd 都等于 1
    期望的输出是 i_mid = 1 和 j_mid = 1

  • 对于位置 0223,我应该得到输出位置 12
    这里的输入是 iStart 为 0,jStart 为 2,同样 iEnd 为 2,jEnd 为 3
    期望的输出是 i_mid = 1 和 j_mid = 2

  • 对于位置 1031,我应该得到输出位置 20
    这里的输入是 iStart 为 3,jStart 为 1,同样 iEnd 为 3,jEnd 为 1
    期望的输出是 i_mid = 2 和 j_mid = 0

我意识到要计算,我们还需要知道数组的长度,因为它是一个 nm 列的矩阵,即 i 的最大值可以是 nj 的最大值可以是 m
因此,对于一个 nm 列的数组,iMax 将是 njMax 将是 m

现在这个函数可以表示为:

void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int iMax, int jMax) {


 //我们需要找到输入位置的中间位置 mid_i 和 mid_j
 System.out.println("midd_i = " + mid_i + " and midd_j = " + mid_j);
}

我通过暴力方法解决了这个问题,但我正在寻找一种更优的解决方案。

在我的方法中,首先我找到了可以在给定位置之间的元素数量,然后我将元素数量除以 2 并遍历位置,直到元素数量的一半,因为在该点之前的元素将是中间值,我的解决方案如下:

void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int jMax) {
   int numberOfRows = (iEnd - iStart) + 1;
   int totalElementsInRows = jMax * numberOfRows;
   int eliminateStartElements = jStart;
   int eliminateEndElements = (jMax - 1) - jEnd;
   int totalElementsPresentBetweenPositions = totalElementsInRows - (eliminateStartElements + eliminateEndElements);
   int halfElement = totalElementsPresentBetweenPositions/2;
   int countElement = 0;
   for(int i = iStart; i <= iEnd; i++) {
      for(int j = 0; j < jMax; j++) {
        countElement++;
        if(halfElement == countElement) {
          System.out.println("midd_i = " + i + " and midd_j = " + j);
          break;
        }
      }
  }
}

我确信应该有一种更优的解决方案,如果有人有更优的解决方案,请帮忙提供。

英文:

I have a 2D array where I want to find the middle position between two given position:
below eg shows the indexes at each position.

00, 01, 02, 03
10, 11, 12, 13
20, 21, 22, 23
30, 31, 32, 33

Inputs:

  • For position 23 and 33 I should get the output position 31.
    Here the inputs are iStart is 2 and jStart is 3, similarly iEnd is 3 and jEnd is 3
    The expected o/p is i_mid = 3 and j_mid = 1

  • For position 00 and 22 I should get the output position 11.
    Here the inputs are iStart is 0 and jStart is also 0, similarly iEnd and jEnd are equal to 1
    The expected o/p is i_mid = 1 and j_mid = 1

  • For position 02 and 23 I should get the output position 12.
    Here the inputs are iStart is 0 and jStart is 2, similarly iEnd is 2 and jEnd is 3
    The expected o/p is i_mid = 1 and j_mid = 2

  • For position 10 and 31 I should get the output position 20.
    Here the inputs are iStart is 3 and jStart is 1, similarly iEnd is 3 and jEnd is 1
    The expected o/p is i_mid = 2 and j_mid = 0

I released that to calculate we should also know the length of the array as it is nxm matrix, ie. max value of i can go is n and max value of j can go is m.
therefor for a nxm array iMax will be n and jMax will be m

Now the function can be represents as:

void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int iMax, int jMax) {


 //We need to find the mid_i and mid_j of the input positions
 System.out.println(&quot;midd_i = &quot;+ mid_i +&quot; and midd_j = &quot;+mid_j);
}

I solved this via a brute force approach, however I'm looking for an optimal solution.

In my approach, first I find the number of elements that can come between the given position and then I divided the number of element by 2 and traverse the position till half of the elements that can come as that point will be the mid, my solution is as followed:

void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int jMax) {
   int numberOfRows = (iEnd - iStart) + 1;
   int totalElementsInRows = jMax * numberOfRows;
   int eliminateStartElements = jStart;
   int eliminateEndElements = (jMax - 1) - jEnd;
   int totalElementsPresentBetweenPositions = totalElementsInRows - (eliminateStartElements + eliminateEndElements);
   int halfElement = totalElementsPresentBetweenPositions/2;
   int countElement = 0;
   for(int i = iStart; i&lt;= iEnd; i++) {
      for(int j = 0; j&lt; jMax; j++) {
        countElement++;
        if(halfElement == countElement) {
          System.out.println(&quot;midd_i = &quot;+ i +&quot; and midd_j = &quot;+j);
          break;
        }
      }
  }
}

I'm sure there should be an optimal solution, If anyone have the optimal solution, please help.

答案1

得分: 1

这是错误的方法,请参阅下面的注释部分。

////////////////////////////

您可以找到两点之间的平均值。当您有点A和点B时,程序必须在两个维度上计算平均值:x=(Ax + Bx)/2。类似地,在y轴上也是如此。

您不必担心数字末尾附加了0.5,因为Java会为您截断它。

英文:

It's a wrong approach, please see the comment section below.

////////////////////////////

You can find the average between the points. When you have point A and point B. The program has to compute average in two dimensions: x=(Ax + Bx)/2. Similarly in the y-axis.

You don't have to worry about .5 appended to end of the number, because Java will truncate it for you.

答案2

得分: 0

应该有一种用几何方法来实现这个的方式...

找到你想要获取的两个位置之间的中点,因此如果你想找到 mat[0][0] 和 mat[2][2] 之间的位置,你可以找到中点:

mid = (Math.abs(x1 - x2) / 2, Math.abs(y1 - y2) / 2)

x = (2 - 0) / 2 = 1
y = (2 - 0) / 2 = 1

因此,在这种情况下答案将是 mat[1][1]

如果是一个不太直接的例子,比如 mat[0][2] 和 mat[3][3]:

首先我们找到中点,如下:

x = (3 - 0) / 2 = 1.5
y = (3 - 2) / 2 = 0.5

将答案四舍五入到最近的整数以获得正确的索引。

英文:

There should be a way to do this with a geometric approach...

Find the midpoint between the two you want to get, so if you wanted to find the position between mat[0][0] and mat[2][2], you find the midpoints:

mid = (Math.abs(x1 - x2) / 2, Math.abs(y1 - y2) / 2)

x = (2 - 0) / 2 = 1
y = (2 - 0) / 2 = 1

so the answer there would be mat[1][1]

if it were a less straightforward example, such as mat[0][2] and mat[3][3]:

we first find the midpoint, such as:

x = (3 - 0) / 2 = 1.5
y = (3 - 2) / 2 = 0.5

round the answers to the nearest whole number to get the right indexes

答案3

得分: 0

你可以通过将具体的数字想象到相应的位置,而不是索引,来简化这个任务,这些数字的范围是从 0 到 n x m - 1。类似于:

 0,  1,  2,  3
 4,  5,  6,  7
 8,  9, 10, 11
12, 13, 14, 15

然后对于每个位于 m[i][j] 的元素应用以下公式:

m[i][j] = i * m[i].length + j

对于每个 k,0 <= k < n x m

 i = k / m
 j = k % m

这在你的方法中看起来像是:

static void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int iMax, int jMax) {
    int s = iStart * jMax + jStart;
    int e = iEnd * jMax + jEnd;
    int mid_i = ((e+s)/2)/jMax;
    int mid_j = ((e+s)/2)%jMax;
    System.out.println("midd_i = "+ mid_i +" and midd_j = "+mid_j);
}

注意:我没有检查有效的输入,例如 iStart <= iEnd <= iMax

用你的输入示例进行测试输出:

getMiddle(0, 0, 2, 2, 4, 4);
getMiddle(0, 2, 2, 3, 4, 4);
getMiddle(1, 0, 3, 1, 4, 4);

midd_i = 1 and midd_j = 1
midd_i = 1 and midd_j = 2
midd_i = 2 and midd_j = 0
英文:

You can simplify the task by imagining concrete numbers in the respective positions instead of the indices, which range from 0 to n x m - 1. Something like :

 0,  1,  2,  3
 4,  5,  6,  7
 8,  9, 10, 11
12, 13, 14, 15

Then for each elemnt at m[i][j] applies

m[i][j] = i * m[i].length + j

and for each k, 0 &lt;= k &lt; n x m

 i = k / m
 j = k % m

which sums up in your method looking like:

static void getMiddle(int iStart, int jStart, int iEnd, int jEnd, int iMax, int jMax) {
    int s = iStart * jMax + jStart;
    int e = iEnd * jMax + jEnd;
    int mid_i = ((e+s)/2)/jMax;
    int mid_j = ((e+s)/2)%jMax;
    System.out.println(&quot;midd_i = &quot;+ mid_i +&quot; and midd_j = &quot;+mid_j);
}

Note: I'm not checking for valid inputs, for example if iStart &lt;= iEnd &lt;= iMax

Test out put with your input example:

getMiddle(0, 0, 2, 2, 4, 4);
getMiddle(0, 2, 2, 3, 4, 4);
getMiddle(1, 0, 3, 1, 4, 4);

midd_i = 1 and midd_j = 1
midd_i = 1 and midd_j = 2
midd_i = 2 and midd_j = 0

huangapple
  • 本文由 发表于 2020年4月4日 05:43:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/61020863.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定