Как правильно написать множество операторов if для массива переменного размера - PullRequest
2 голосов
/ 24 декабря 2010

У меня есть код, который берет повторяющиеся локальные окрестности из большого массива. Я могу установить код, чтобы дать мне окрестности 3х3 или окрестности любого другого размера, такие как 5х5 или 11х11. Затем мне нужно проверить различные вещи о массиве, как описано ниже. Я начал писать с множеством вложенных операторов 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 ]

1 голос
/ 24 декабря 2010

Вы можете использовать массив указателей на функции, чтобы указать, что нужно проверять для каждого квадрата.

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 для каждого размера.

1 голос
/ 24 декабря 2010

Создать помощника, который извлекает одномерный вектор.Затем выполните что-то вроде:

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

Затем напишите функцию, которая берет один из этих новых векторов и проверяет ваши критерии.Может быть, если и тому подобное, но не слишком много.

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)
1 голос
/ 24 декабря 2010

Составьте список / массив триплетов, которые вы хотите проверить:

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

Это учитывает код, который выполняет проверку, из элементов, которые вы хотите проверить. Он позволяет генерировать элементы для проверки и их границы в зависимости от того, что вы хотите: программно или просто жестко их кодировать. Если вы в конечном итоге жестко запрограммируете, по крайней мере, код будет выглядеть очень просто: это будет просто объявление массива.

1 голос
/ 24 декабря 2010

Полагаю, это зависит от вашей парадигмы программирования.

В качестве примера в среде программирования списка, такой как 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.

Код не является оптимальным, поскольку он не закорачивает И и продолжает вычислять до конца, а затем И все результаты.Это облегчает поддержку кода.В зависимости от ваших требований к производительности, которые могут (или не могут) быть возможными в вашем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...