二维数组:二维数组的子平方的元素之和
2D array: Sum of elements of a subsquare of the 2d array
给定一个2D数组,我可以将其所有元素添加到一个sum变量中。假设一个4x4阵列:
1 2 3 4
1 2 2 3
1 2 2
1 1 3 3
我的代码将其所有元素相加,就是做一个for循环:
for (i = 0; i < rows; i++)
{
for (j = 0; j < columns; j++)
{
sum += somearray[i][j];
}
}
我认为这是正确的,假设所有变量都被正确地声明了。然而,我在对同一数组中的3x3单元格求和时遇到了问题。我想找到产生最小和的3x3单元。
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j+++
{
sum += somearray[i][j];
}
}
我相信这是从某个数组[0][0]开始的3x3单元格的总和。我不知道如何从这里获得所有其他3x3单元格组合,并将它们进行比较,以找到最低的3x3单元格值。如果我能找到下一个3x3单元格,我知道我可以使用某种比较语句,并将sum变量更改为下一个sum,如果它更低的话。
我怎样才能做到这一点?我需要在for循环中添加更多层吗?
让我们从定义开始:
size_t rows; // number of rows
size_t columns; // number of columns
int array[rows][columns];
助手功能:
int sum(size_t row, size_t column)
{
int res = 0;
if (row > rows - 3 || column > columns - 3)
{
abort(); // we can out of index operations here...
}
for (size_t i = 0; i < 3; ++i)
{
for (size_t j = 0; j < 3; ++j)
{
res += array[i + row][j + column];
}
}
return res;
}
现在我们可以开始了。。。
int min_value = INT_MAX; // Just the maximum we can imaging
size_t min_row = 0, min_column = 0; // whatever
for (size_t i = 0; i <= rows - 3; ++i)
{
for (size_t j = 0; j <= columns - 3; ++j)
{
int value = sum(i, j);
if (value < min_value)
{
min_value = value;
min_row = i;
min_column = j;
}
}
}
... // done - here min_value is the minimum sum,
// and min_row, min_column are indexes of the 3x3 entry
您编写的代码,两个for循环都停止在3,可以计算出您想要的从[0][0]开始的3x3子矩阵中的数字,正如您所说。你现在需要做的是:
-
确定你的所有出发点,确保从那里开始有3行3列,包括元素,并且每种可能调用该函数一次起点和
-
扩展该代码,使其可以从矩阵
以下是我们如何进行第1点:
你有一个4x4矩阵,但我们可以很容易地将其推广到NxM矩阵。N表示有N行,即每列有N个元素。所以让我们考虑一个专栏。如果你有N个元素,你能找到多少组3个连续元素?注意,它不是N-3(这看起来是一个明显的答案,但它是错误的):
- 对于N=3个元素,它只有1(如果有123,则组为123)
- 如果N=4个元素,则有2个(如果有1234,则组为123和234)
- 在N=5个元素的情况下有3个(如果你有12345,234345)
所以一般来说,你有N-3+1个群(当然你可以认为它是N-2,但我更喜欢表达3,因为这是我们每次取的元素的数量)。
同样的方法也可以应用于列:如果它们是M,则可以采用M-3+1组。
也就是说,在一个NxM矩阵中,你能找到多少个3x3子矩阵?首先,你可以找到所有"垂直"的3组,它们是N-3+1。对于他们每个人,你能组成多少个3人的"水平"小组?M-3+1。那么你总共有(N-3+1)*(M-3+1)3x3个子矩阵。这是为了检查每个子矩阵而必须进行的迭代次数。这些N-3+1元素中的每一个都是一行(我们垂直移动,也就是沿着一列移动,所以这些都是行),所以这是一个我们可以开始检查矩阵的元素,前提是我们有足够的水平空间,也就是说,有足够的列。对于这些行中的每一行,我们都必须检查M-3+1列(沿着一行水平移动),其中3x3子矩阵可以开始。
int min_found = 0; // So far we haven't found a minimum yet
int min_value, min_row, min_column;
int max_rows = (N-3+1);
int max_columns = (M-3+1);
for (int start_row = 0; start_row < max_rows; start_row++) {
for (int start_column = 0; start_column < max_columns; start_column++) {
int current_sum = calculate_sum_of_submatrix(start_row, start_column);
if ( (min_found == 0) || (min_found == 1 && current_sum < min_value) )
min_value = current_sum;
min_row = start_row;
min_column = start_column;
min_found = 1;
}
}
}
cout << "The 3x3 submatrix whose elements have the minimum sum "
<< "starts at row " << min_row << " and column " << min_column
<< ", and the sum is " << min_sum << endl;
在您的情况下(N=4,M=4),我们将有N-3+1=2行进行检查,M-3+1=2列。因此,我们将从[0][0]开始,然后内循环将我们带到[0][1],然后内环路将结束,我们将继续到外环路,这将带我们到第1行,内环路将检查[1][0]和[1][1]。那就完了。到那时,我们已经检查了所有4个3x3子矩阵,我们就会知道最小值。
现在,第2点:我们必须调整您已经拥有的函数,这样就不会总是从[0][0]开始,而是从我们想要的地方开始。这很容易,我们只需要在一个由起始位置(在代码中总是[0][0])和[i][j]索引之和给出的位置读取矩阵。像这样:
int calculate_sum_of_submatrix(int start_row, int start_column) {
int sum = 0;
for (int i = 0; i < 3; i++) { // I would replace i with "submatrix_row"
for (int j = 0; j < 3; j++) { // I would replace j with "submatrix_column"
sum += somearray[start_row + i][start_column + j];
}
}
return sum;
}
这样就可以了。
- 将二维数组的所有元素插入到一维数组中
- 元素在二维数组 c++ 中的出现次数
- 在二维数组中查找第二大元素
- 在给定元素在螺旋上的位置的情况下,在二维数组中查找元素
- 如何为映射和priority_queue编写比较器,其中元素是二维数组
- 如何将 50 行和 50 列的二维数组编码为一个为元素随机分配星号的函数?
- 如何删除二维数组中的元素
- 我无法将二维数组的两个元素的差异分配给C++中其他数组的元素?
- 在 c 和 c++ 中,二维数组的元素是什么类型?
- 如何在默认和二维数组中找到顺序扩大元素的位置
- C++ 中二维数组中未知数量的元素
- 是一个二维数组的名称,它在C++中的第一个元素的地址
- 从二维数组中给定的索引中求对角线元素的和
- 二维数组的最小/最大元素
- 随机修改二维数组元素
- 二维数组:二维数组的子平方的元素之和
- 将二维数组元素复制到另一个具有其他大小的二维数组中
- 如何将元素添加到二维数组/矩阵的随机位置
- C++:用满足特定要求的二维数组的元素制作数组
- 获取动态二维数组元素的行/列