开发者

How to write lots of if statements for a variable-sized array nicely

I've got some code that takes repeated local neighbourhoods from a large array. I can set the code to give me 3x3 neighbourhoods, or any other sized neighbourhoods such as 5x5 or 11x11. I then need to check various things about the array, as detailed below. I've started writing it with loads of nested if statements, but thought there must be a better way!

   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

Given the array above I want to check if the values in [0, 2] and [1, 2] are less than a threshold, and the values in [3, 2] and [4, 2] are greater than the threshold. I then want to do the same thing with a vertical line through the centre (rather t开发者_C百科han the horizontal line in the example I gave), and the same for both diagonals.

At the moment I can't see any way to do this without loads of if statements which will get very confusing and difficult to maintain very quickly. I'm sure there must be a better way to do it - any ideas?


You can use an array of function pointers to specify what needs to be checked for each square.

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

If you need different sizes, just make a different check_functions array for each size.


I guess that depends on your programming paradigm.

As an example in a list programming environment such as Mathematica you can do:

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

And call the function with

f[{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},5]  

f[ ] returns True if your conditions are met, False otherwise.

The code is not optimal, since it does not short-circuit the AND and continue evaluating through the end, and then ANDs all results. That results in easier to maintain code. Depending on your performance requirements that may (or not) be possible in your case.


Create a helper that extracts a 1D vector. Then do something like:

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).

Then write a function that takes one of these new vectors and checks your criteria. It might have ifs and the like, but not too many.

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

Now your logic becomes

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


Make a list/array of triplets that you want to check:

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

Then loop through the trips array and check each in your matrix, M.

Using java, here's the code for checking all things meet some lower bound:

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

The same type of thing can be extended to check for upper bounds as well:

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

This factors the code that does the checking from the elements you want to check. It allows you to generate the elements to check and their bounds whichever way you want: either programmatically or just hard-coding them. If you end up hard-coding, at least the code will look very simple: it will just be an array declaration.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜