我有一个land=0
和water=1
的2D数组。我已经制定了一个逻辑来获得最大可用范围,即2D阵列中可用的最大连续着陆位。然而,当我在纸上使用这种逻辑时,它给出了正确的答案,但在系统上却没有给出正确的答案。
假设数组Array[3][9]
有元素:
0 1 1 0 1 0 0 0 1
0 1 0 1 0 0 0 0 0
1 1 1 1 1 0 0 1 1
在下面的代码中,数组是input2。
输出应为10。
我开发的逻辑是
int countContigious(char* array[],int x,int y,int row1,int col1)
{
if(x<0||x>=row1||y<0||y>=col1||array[x][y]!=0)
{
return 0;
}
else
{
array[x][y]=2;
return 1+countContigious(array,x-1,y,row1,col1)+countContigious(array,x+1,y,row1,col1)+countContigious(array,x,y-1,row1,col1)+countContigious(array,x,y+1,row1,col1);
}
}
int largestSize(int input1[],char* input2[])
{
int row,col,i,j;
int count=0;
int result=0;
row=input1[0];
col=input1[1];
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
if(input2[i][j]==0)
{
count=countContigious(input2,i,j,row,col);
if(count>result)
{
result=count;
}
}
}
}
return result;
}
据我说它应该在变量结果中返回答案。任何人都能说出我的逻辑中有什么问题吗?
答案 0 :(得分:0)
你有一个2D数组。遍历它的常用方法是循环加倍。 通常的顺序是这样的: 第1行 - 第1列 第1行 - 第2列 .. 第1行 - 最后一列 第2行 - 第1列 ... 最后一行 - 最后一栏
假设您使用上述订单,您可能希望执行以下操作:
每当你找到一个土地位时,探索该位置的右侧,上部,右上部,右下部和底部的阵列(在此步骤之前访问其他方向)并找到最大长度contigius zeros。
这是一个非常天真的例子:
#include <stdio.h>
int main() {
const int N = 4;
const int M = 5;
int a[4][5] =
{
{ 1, 0, 0, 0, 0},
{ 0, 0, 1, 1, 0},
{ 0, 1, 0, 0, 0},
{ 0, 0, 0, 0, 0}
};
/* A naive implementation, which can optimized.
* Some initializations are not needed.
*/
int i, j, k, z, len;
int max_len = -1;
// traverse the array in the order described before
for(i = 0 ; i < N ; ++i)
{
for(j = 0 ; j < M ; ++j)
{
/* Land bit found! Explore the array in the needed directions. */
if(a[i][j] == 0) {
// remember where we start from
k = i;
z = j;
len = 0;
// search right
// while we are inside the limits of the array
// (here we need to check only the columns, since
// we move to the right)
while(z < M) {
// and we find land bits
if(a[k][z++] == 0)
len++; // increase the current length
else // we want contiguous land bits
break; // we found a water bit, so break this loop
}
// is the current length better than the current found?
if(len > max_len)
max_len = len; // yes, so update max_len
// return back to initial cell we started from
k = i;
z = j;
len = 0;
// search down
while(k < N) {
if(a[k++][z] == 0)
len++;
else
break;
}
if(len > max_len)
max_len = len;
k = i;
z = j;
len = 0;
// search right and down
while(k < N && z < M) {
if(a[k++][z++] == 0)
len++;
else
break;
}
if(len > max_len)
max_len = len;
k = i;
z = j;
len = 0;
// search upper
while(k >= 0) {
if(a[k--][z] == 0)
len++;
else
break;
}
if(len > max_len)
max_len = len;
k = i;
z = j;
len = 0;
// search upper and right
while(k >= 0 && z < M) {
if(a[k++][z++] == 0)
len++;
else
break;
}
if(len > max_len)
max_len = len;
}
}
}
printf("max_length = %d\n", max_len);
return 0;
}
在理解了天真的方法之后,试着看看你的方法错过了什么。使用纸张并尝试使用较小的示例。该站点不仅用于调试。 :)
[编辑]
正如弗洛里斯所说,这个例子假设土地是一条直线,在任何方向。
根据Floris的回答,为了让它适合U形土地,你需要像这样修改你的countC
:
else
{
input2[x][y]=2;
return 1+countC(input2,x-1,y,r1,c1)+
countC(input2,x+1,y,r1,c1)+
countC(input2,x,y-1,r1,c1)+
countC(input2,x,y+1,r1,c1)+
countC(input2,x+1,y+1,r1,c1)+
countC(input2,x+1,y-1,r1,c1)+
countC(input2,x-1,y+1,r1,c1)+
countC(input2,x-1,y-1,r1,c1);
}
如你所见,你也需要进入对角线。
答案 1 :(得分:0)
您编写的代码可以成为工作程序的一部分 - 换句话说,您的逻辑是正确的。我怀疑你的问题在于“你没有展示的代码”。为了演示,我已经将您的代码转换为完整的工作程序 - 根本不需要更改代码。
请注意,在您编写
时,您正在做一些有潜在危险的事情if(x<0||x>=r1||y<0||y>=c1||input2[x][y]!=0)
由于编译器“短路”OR语句,当任何一个索引超出范围时,你永远不会评估input2[x][y]
- 但我不认为这是你应该依赖的行为。首先测试边界会更安全,并返回0
以获得“越界”;然后在单独的if
语句中测试该位置的非零值(现在是一个“有效”位置)。
#include <stdio.h>
#include <stdlib.h>
int countC(char* input2[],int x,int y,int r1,int c1)
{
if(x<0||x>=r1||y<0||y>=c1||input2[x][y]!=0) // <<<< dangerous! better have two ifs >>>>
{
return 0;
}
else
{
input2[x][y]=2;
return 1+countC(input2,x-1,y,r1,c1)+countC(input2,x+1,y,r1,c1)+countC(input2,x,y-1,r1,c1)+countC(input2,x,y+1,r1,c1);
}
}
int largestSize(int input1[],char* input2[])
{
int r,c,i,j;
int count=0;
int result=0;
r=input1[0];
c=input1[1];
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
if(input2[i][j]==0)
{
count=countC(input2,i,j,r,c);
if(count>result)
{
result=count;
}
}
}
}
return result;
}
// <<< new function added to create a "variable size 2D array"
char **twoDchar(int rc, int cc) {
char** p;
int ii;
p = malloc(rc * sizeof (char*));
p[0]=malloc(rc * cc * sizeof(char));
for(ii=1; ii<rc; ii++) {
p[ii]=p[0]+ii*cc*sizeof(char);
}
return p;
}
// <<< added main() function to test the code >>>
int main(void) {
int dims[]={3,9};
char land[3][9]={ \
{0, 1, 1, 0, 1, 0, 0, 0, 1}, \
{0, 1, 0, 1, 0, 0, 0, 0, 0}, \
{1, 1, 1, 1, 1, 0, 0, 1, 1}};
char** lp;
int ii, jj;
lp = twoDchar(3,9);
for(ii=0;ii<3;ii++)
for(jj=0;jj<9;jj++) {
lp[ii][jj]=land[ii][jj];
}
printf("biggest mass is %d\n", largestSize(dims,lp));
}
当我运行上述内容时,我确实得到了答案10
。
更新以获取“U形土地”的示例:
char land[3][9]={\
{0, 1, 1, 0, 1, 0, 1, 0, 1},\
{0, 1, 0, 1, 0, 0, 1, 0, 0},\
{1, 1, 1, 1, 1, 0, 0, 0, 1}};
我按预期得到答案9
。
注意我在问题首次出现时所做的评论:
我建议您包含创建2D“数组”的代码 - 因为你实际上创建了一个数组数组而不是静态2D数组 阵列。重要的是要展示你是如何做到的 - 它可能包含一个 bug,任何人都需要运行你的代码。
现在我仔细看了一下,看起来确实可能是问题的根源(尽管你从来没有展示过你是如何想出2D阵列的。)