如何很好地为可变大小的数组编写大量的if语句

时间:2010-12-24 15:45:21

标签: arrays algorithm

我有一些代码从大型数组中获取重复的本地邻域。我可以设置代码给我3x3邻居,或任何其他大小的邻居,如5x5或11x11。然后我需要检查有关阵列的各种事情,详情如下。我已经开始用大量嵌套的if语句编写它,但是认为必须有更好的方法!

   0  1  2  3  4
   --------------
0 |1  2  3  4  5
1 |6  7  8  9  10
2 |11 12 13 14 15
3 |16 17 18 19 20
4 |21 22 23 24 25

鉴于上面的数组,我想检查[0,2]和[1,2]中的值是否小于阈值,[3,2]和[4,2]中的值是否大于门槛。然后,我希望通过中心的垂直线(而不是我给出的示例中的水平线)做同样的事情,对于两个对角线都是一样的。

目前,如果没有if语句会导致非常混乱且难以快速维护,我无法看到任何方法。我确信必须有更好的方法 - 任何想法?

4 个答案:

答案 0 :(得分:1)

我想这取决于你的编程范式。

作为Mathematica等列表编程环境中的一个例子,你可以这样做:

f[x_,bound_] :=
 With[{d = (IntegerPart[Dimensions[x][[1]]/2] + 1)},
  And @@ Flatten[
    Table[{x[[d, i]]     > bound, 
           x[[d, i + d]] < bound, 
           x[[i, d]]     > bound, 
           x[[i + d, d]] < bound}, 
    {i, d - 1}]]]  

调用该函数
f[{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},5]  

f [] 如果满足您的条件,则返回True,否则返回False。

代码不是最优的,因为它不会使AND短路并继续进行评估,然后对所有结果进行AND运算。这样可以更轻松地维护代码。根据您的性能要求,可能(或不)可能。

答案 1 :(得分:1)

创建一个提取1D向量的帮助器。然后做一些事情:

vector v1 = array.row(2);
vector v2 = array.column(2);
vector v3 = array.diagonal(top left to bottom right);
vector v4 = array.diagonal(bottom left to top right).

然后编写一个函数,它接受这些新向量之一并检查您的标准。它可能有ifs之类,但不是太多。

return (vec[0] and vec[1] < threshold) and 
       (vec[3] and vec[4] > threshold)

现在您的逻辑变为

meets_criteria(v1) or meets_criteria(v2) or 
meets_criteria(v3) or meets_criteria(v4)

答案 2 :(得分:1)

制作要检查的三元组列表/数组:

trips = [[X1, Y1, BOUND1], [X2, Y2, BOUND2], ..., [Xn, Yn, BOUNDn]]

然后循环遍历trips数组并检查矩阵中的每一个M

使用java,这里是用于检查所有符合某个下限的代码:

private boolean boundsCheck(int[][] M, int[][] trips)
{
   for (int[] trip : trips)
   {
      if (M[trip[0]][trip[1]] > trip[2]) return false;
   }
   return true;
}

同样类型的东西也可以扩展到检查上限:

private boolean boundsCheck(int[][] M, int[][] tripsLower, int[][] tripsUpper)
{
   for (int[] trip : tripsLower)
   {
      if (M[trip[0]][trip[1]] > trip[2]) return false;
   }
   for (int[] trip : tripsUpper)
   {
      if (M[trip[0]][trip[1]] < trip[2]) return false;
   }
   return true;
}

这会影响从您要检查的元素进行检查的代码。 它允许您以任何方式生成要检查的元素及其边界:以编程方式或仅对其进行硬编码。如果最终硬编码,至少代码看起来很简单:它只是一个数组声明。

答案 3 :(得分:1)

您可以使用函数指针数组来指定每个方块需要检查的内容。

int a = ...;
int b = ...;
bool bigger_than_a(int x) { return x > a; }
bool smaller_than_b(int x) { return x < b; }

bool (*)(int) check_functions[5][5] = {
    NULL, bigger_than_a, bigger_than_b, NULL, NULL,
    ...
}

int x_start = ...;
int y_start = ...;
for (int x = 0; x < 5; x++) {
  for (int y = 0; y < 5; y++) {
    if (check_functions[x][y] != NULL &&
        !check_functions[x][y](array[x_start + x][y_start + y]) {
           ...check failed...
    }
  }
}

如果您需要不同的尺寸,请为每种尺寸制作不同的check_functions数组。