在c ++中找到二维数组中的最大区域
Posted
技术标签:
【中文标题】在c ++中找到二维数组中的最大区域【英文标题】:Find largest area in 2d array in c++ 【发布时间】:2013-03-20 06:53:27 【问题描述】:我需要在 C++ 中编写递归函数,在仅包含 1 或 0 的二维数组中找到数字“1”的最大区域。
例子:
int Arr[5][8] =
0, 0, 0, 0, 1, 1, 0, 0, ,
1, 0, 0, 1, 1, 1, 0, 0, ,
1, 1, 0, 1, 0, 1, 1, 0, ,
0, 0, 0, 1, 1, 1, 1, 0, ,
0, 1, 1, 0, 0, 0, 0, 0, ,
;
视觉示例:http://s23.postimg.org/yabwp6h23/find_largest.png
这个数组的最大面积是 12,第二大是 3,第三大是 2。
我想用类似于洪水填充算法的东西来做到这一点,但就是不知道怎么做。
【问题讨论】:
洪水填充会起作用。如果您卡在某个地方,您应该发布您的尝试并描述您的问题。 也许对于每个等于 1 的元素,检查 North、South East 和 West,然后增加并再次检查。此外,将递增的数组索引添加到忽略列表。洪水填充算法有很多,知道哪个是最好的会很有趣。 一个相关的问题是***.com/questions/2478447/… 【参考方案1】:我想用类似于洪水填充算法的东西来做到这一点
我认为这是一个很好的方法。对任何1
应用洪水填充,计算其中的一个并将它们替换为零。
重复直到网格完全由零组成。
以下将不按特定顺序打印出连接组件的大小:
#include <iostream>
constexpr int N = 5;
constexpr int M = 8;
int arr[N][M] =
0, 0, 0, 0, 1, 1, 0, 0, ,
1, 0, 0, 1, 1, 1, 0, 0, ,
1, 1, 0, 1, 0, 1, 1, 0, ,
0, 0, 0, 1, 1, 1, 1, 0, ,
0, 1, 1, 0, 0, 0, 0, 0, ,
;
int fill(int arr[N][M], int r, int c)
int count = 0;
if (r < N && arr[r][c])
for (int i = c; i >= 0 && arr[r][i]; --i)
arr[r][i] = 0;
count += fill(arr, r + 1, i) + 1;
for (int i = c + 1; i < M && arr[r][i]; ++i)
arr[r][i] = 0;
count += fill(arr, r + 1, i) + 1;
return count;
int print_components(int arr[N][M])
for (int r = 0; r < N; ++r)
for (int c = 0; c < M; ++c)
if (arr[r][c])
std::cout << fill(arr, r, c) << std::endl;
int main()
print_components(arr);
【讨论】:
我不知道你想怎么做,但如果你用0
's 替换1
's,你必须小心。否则,您可以将一个连接的表面一分为二,并且不再承认它们一开始就属于一起。【参考方案2】:
类似的,
int max_area = 0;
foreach y
foreach x
if (pos[y][x] == 1 && !visited[y][x])
int area = 0;
Queue queue = new Queue();
queue.push(new Point(x, y));
visited[y][x] = true;
while (!queue.empty())
Point pt = queue.pop();
area++;
foreach neightboor of pt (pt.x±1, pt.y±1)
if (pos[neightboor.y][neightboor.x] == 1 && !visited[neightboor.y][neightboor.x])
visited[neightboor.y][neightboor.x] = true;
queue.push(new Point(neightboor.x, neightboor.y));
if (area > max_area)
max_area = area;
【讨论】:
顺便说一句:OP 要求递归解决方案,因此洪水填充和回溯应该可以一起工作【参考方案3】:快速方法,但我不知道是否有办法以一种理智的方式做到这一点(递归 对每个元素的调用不适用于 C++,因为调用堆栈是有限的)
int maxy = 5
int maxx = 8
int areasize(int x, int y)
if (x < 0 || y < 0 || x > maxx || y > maxy || !Arr[y][x])
return 0;
Arr[y][x] = 0;
return 1
+ areasize(x + 1, y)
+ areasize(x - 1, y)
+ areasize(x, y + 1)
+ areasize(x, y - 1);
maxarea = 0;
for (int y = 0; y < maxy; y++)
for (int x = 0; x < maxx; x++)
maxarea = std::max(maxarea, areasize(x, y));
【讨论】:
感谢提示,我忘了插入擦除语句。【参考方案4】:bool visited[5][8];
int i,j;
// variables for the area:
int current_area = 0, max_area = 0;
int Arr[5][8]= // type your map of values here
// functions
void prepare_visited_map()
for(i=0;i<5;i++)
for(j=0;j<8;j++) visited[i][j] = false;
// recursive function to calculate the area around (x,y)
void calculate_largest_area(int x, int y)
if(visited[x][y]) return;
// check if out of boundaries
if(x<0 || y<0 || x>=5 || y>=8) return;
// check if the cell is 0
if(!Arr[x][y])
visited[x][y] = true;
return;
// found a propper cell, proceed
current_area++;
visited[x][y] = true;
// call recursive function for the adjacent cells (north, east, south, west)
calculate_largest_area(x,y-1);
calculate_largest_area(x+1,y);
calculate_largest_area(x,y+1);
calculate_largest_area(x-1,y);
// by the end of the recursion current_area will hold the area around the initial cell
// main procedure where the above functions are used
int mian()
// calculate the sorrounding area of each cell, and pick up the largest of all results
for(i=0;i<5;i++)
for(j=0;j<8;j++)
prepare_visited_map();
calculate_largest_area(i,j);
if(current_area > max_area) max_area = current_area;
printf("Max area is %d",max_area");
希望这会有所帮助:)
【讨论】:
以上是关于在c ++中找到二维数组中的最大区域的主要内容,如果未能解决你的问题,请参考以下文章