您有八种或多或少发生的特殊情况,有时这些情况可能会同时发生,如果您只有一行或只有一列或两者都有:
[]====+=====================================+====[]
|| UL | Upper row | UR ||
++----+-------------------------------------+----++
|| Le | Main block | Ri ||
|| ft | | gh ||
|| c | | t ||
|| ol | | co ||
|| | | l ||
|| | | ||
++----+-------------------------------------+----++
|| LL | Lower row | LR ||
[]====+=====================================+====[]
我应该为每个循环使用不同的循环,这样您就可以预先知道哪些单元格可以访问并且不必进行任何测试。如果数组只有一行或一列,您必须考虑可能遇到的特殊情况,仅此而已。
我假设您有一个数组指针数组,但您没有说出来,但它使用[] 运算符简化了对矩阵单元的访问。
inline int max2(int a, int b)
{
return a > b ? a : b;
}
inline int max3(int a, int b, int c)
{
return max2(max2(a, b), c);
}
inline int max4(int a, int b, int c, int d)
{
return max2(max2(a, b), max2(c, d));
}
inline int max6(
int a, int b, int c,
int d, int e, int f)
{
return max2(max3(a, b, c), max3(d, e, f));
}
inline int max9(
int a, int b, int c,
int d, int e, int f,
int g, int h, int i)
{
return max3(max3(a, b, c), max3(d, e, f), max3(g, h, i));
}
void max_value(int **in, int **out, int rows, int cols)
{
if (rows > 1) {
/* to avoid many calculations */
int rows_1 = rows - 1, rows_2 = rows - 2;
if (cols > 1) { /* cols > 1 && rows > 1 */
int cols_1 = cols - 1, cols_2 = cols - 2;
/* first consider the four corners */
/* UL */
out[0][0] = max4(
in[0][0], in[0][1],
in[1][0], in[1][1]);
/* LR */
out[rows_1][cols_1] = max4(
in[rows_2][cols_2],in[rows_2][cols_1],
in[rows_1][cols_2],in[rows_1][cols_1]);
/* LL */
out[rows_1][0] = max4(
in[rows_2][0], in[rows_2][1],
in[rows_1][0], in[rows_1][1]);
/* UR */
out[0][cols_1] = max4(
in[0][cols_2], in[1][cols_2],
in[0][cols_1], in[1][cols_1]);
/* next the two side columns */
for(row = 1; row < rows_1; row++) {
/* left */
out[row][0] = max6(
in[row-1][0], in[row-1][1],
in[row][0], in[row][1],
in[row+1][0], in[row+1][1]);
/* right */
out[row][cols_1] = max6(
in[row-1][cols_2], in[row-1][cols_1],
in[row][cols_2], in[row][cols_1],
in[row+1][cols_2], in[row+1][cols_1]);
} /* for */
/* ... and the top/bottom rows */
for(col = 1; col < cols_1; col++) {
/* top */
out[0][col] = max6(
in[0][col-1], in[0][col], in[0][col+1],
in[1][col-1], in[0][col], in[0][col+1]);
/* bottom */
out[row_1][col] = max6(
in[row_2][col-1], in[row_2][col], in[row_2][col+1],
in[row_1][col-1], in[row_1][col], in[row_1][col+1]);
} /* for */
/* and finally, the main block */
for(row=1; row < row_1; row++) {
for(col=1; col < col_1; col++) {
out[row][col] = max9(
in[row-1][col-1],in[row-1][col],in[row-1][col+1],
in[row][col-1],in[row][col],in[row][col+1],
in[row+1][col-1],in[row+1][col],in[row+1][col+1]);
} /* for */
} /* for */
} else { /* rows > 1 && cols == 1 */
/* we collapsed to three zones in one column */
/* UL == UR */
out[0][0] = max2(
in[0][0],
in[1][0]);
/* LL == LR */
out[row_1][0] = max2(
in[row_2][0],
in[row_1][0]);
/* main block */
for(row = 1; row < rows_1; row++) {
out[row][0] = max3(
in[row-1][0],
in[row][0],
in[row+1][0]);
} /* for */
} /* if */
} else { /* rows == 1 */
/* the nine zones collapse to three */
if (cols > 1) {
/* UL == LL */
out[0][0] = max2(in[0][0], in[0][1]);
/* UR == LR */
out[0][col_1] = max2(in[0][col_2], in[0][col_1]);
/* the main part */
for(col=1; col < cols_1; col++)
out[0][col] = max3(in[0][col-1],in[0][col],in[0][col+1]);
} /* for */
} else { /* rows == 1 && cols == 1 */
/* ... or one */
out[0][0] = in[0][0];
}
} /* if */
} /* max_value */