《返回二维整数数组中最大子数组的和》团队合作及第七周学习进度条
团队合作第二棒:由井小普、张贺冥思苦想写制,虽然结果并没有出来,但我们学会了一个问题的分解思路,并且从中学会了很多东西,收获颇多。
下面开始步入正题:
首先,王老板题目要求是:
一、设计思想:
1.我们首先想到,既然二维数组中的每个数都有其对应的行值、列值,所以可以定义一个二维数组中数值的类,其中可以定义变量行、列、本身的值,包含get、set函数,有参、无参函数,(此时二维数组可以看成一维数组)代码package ErWeiShuZu;
package ErWeiShuZu; public class TwoDimension { int r,l,num; public int getR() { return r; } public void setR(int r) { this.r=r; } public int getL() { return l; } public void setL(int l) { this.l=l; } public int getNum() { return num; } public void setNum(int num) { this.num=num; } public TwoDimension() { } public TwoDimension(int r,int l,int num) { this.r=r; this.l=l; this.num=num; } public void set(int r2, int l2, int num2) { // TODO Auto-generated method stub this.r=r2; this.l=l2; this.num=num2; } //---读写,toString }
2.然后开始判断数组中的两个数是否连通,连通为true,不连通为false(关键思想是如果两个数连通,它们必定是同一行或者同一列,并且另一个维度的数值相差1),函数代码如下:
//----连通为true,不连通为false
public static boolean judge(TwoDimension a,TwoDimension b)
{
boolean flag=true;
if(Math.abs(a.getR()-b.getR())>2||Math.abs(a.getL()-b.getL())>2)
{
flag=false;
}
else
{
flag=true;
}
return flag;
}
3.然后想到老师的提示,将数组中的所有整数拿出来,判断是否连通,不连通的话判断连通代价,于是我们将所有非负数放在另一个数组b中,进行下一步运算操作使用。代码如下:
//-----把所有的正数都拿出来,行列值不变
public static TwoDimension[] Positive(TwoDimension[]a)
{
TwoDimension[] b=new TwoDimension[a.length];
for(int i=0;i<a.length;i++)
{
if(a[i].getNum()>=0)
{
b[i]=a[i];
}
else
{
b[i]=new TwoDimension();
b[i].setNum(-1);
b[i].setR(a[i].getR());
b[i].setL(a[i].getL());
}
}
return b;
}
4.之后想到我们可以通过寻找最大正数及其周围的连通情况,可以慢慢将整个数组“浸透”,如果最大值周围四个数分别与最大值相加和都为负数,所以需要将最大值舍去,找到次大值继续之前的算法。排序算法如下:
//---排序,升序
public static TwoDimension[] Sort(TwoDimension[] b)
{
TwoDimension t=new TwoDimension();
for(int i=0;i<b.length;i++)
{
int k=i;
for(int j=i+1;j<b.length;j++)
if(b[j].getNum()<b[k].getNum())
{
k=j;
}
if(k!=i)
{
t=b[i];
b[i]=b[k];
b[k]=t;
}
}
return b;
}
//---sign判正负,正数就相加。
public static int sign(TwoDimension b,TwoDimension c)
{
int sum=0;
if((c!=null)&&(c.getNum()>0))
sum=c.getNum()+b.getNum();
return sum;
}
//----周围数求和
public static int sum1(TwoDimension[] a,TwoDimension b)
{
int sum=0;
TwoDimension d [];
d=Zhou(a,b);
for(int i=0;i<4;i++)
{
TwoDimension c = find(a,d[i].getR(),d[i].getL());
sum+=sign(b,c);
}
return sum;
}
//----周围的数单独拿出来放到数组里
public static TwoDimension[] Zhou(TwoDimension[] a,TwoDimension b){
TwoDimension[] zhou=new TwoDimension[4];
int r[]=new int[4];
int l[]=new int[4];
r[0]=b.getR()-1;
l[0]=b.getL();
r[1]=b.getR()+1;
l[1]=b.getL();
r[2]=b.getR();
l[2]=b.getL()-1;
r[3]=b.getR();
l[3]=b.getL()+1;
return zhou;
}
}
卡住的函数(不知道怎样将值连接起来)如下:
//------从最大的数开始连,参数a为用户输入的二维数组,b为排序后的正数 public static TwoDimension[] Lian(TwoDimension[] a,TwoDimension b[]) { int k=-1; TwoDimension[] zi=new TwoDimension[a.length]; for(int i=b.length-1;i>=0;i--) { TwoDimension[] zhou=Zhou(a,b[i]); if(attribute(a,b[i])==false)//都为负,放弃 { //i--; } else { zi[k++]=b[i];//可以连通 TwoDimension[] si=single(a,b[i]); while(si1!=null)//------------卡在这了,每个人都有四个孩子,都得判断跟周围能否连 { for(int j=0;j<4;j++) { if(si[j]!=null)//--si不为空说明可以连通 { zi[k++]=si[j]; TwoDimension[] si1=single(a,si[j]); } } } } } return zi; }
判断连通属性
//---------连通属性,如果该正数与周围的数相加,两两相加都小于0,flag=false,放弃他 public static boolean attribute(TwoDimension[] a,TwoDimension b) { boolean flag=true; int j=0; TwoDimension c[];//b周围的数 c=Zhou(a,b); for(int i=0;i<4;i++) { if(c[i]!=null&&(b.getNum()+c[i].getNum()<0)) { j++; } } if(j==4) //与周围四个相加都是负数 { flag=false; } return flag; }
//--参数 当前连入的数,看周围的能否连,返回可以连的数,在循环调用 public static TwoDimension[] single(TwoDimension[] a,TwoDimension b) { TwoDimension[] zi = null; TwoDimension[] zhou=Zhou(a,b); if(attribute(a,b)==false)//都为负,放弃 zi=null; else { for(int j=0;j<4;j++) { if(zhou[j]!=null&&(b.getNum()+zhou[j].getNum()>0)) { zi[j]=zhou[j]; } else { zi[j]=null; } } } return zi; }
最后连通数组放在数组里,求和
//------求和,把最终结果求和 public static int sum(TwoDimension[] zi) { int sum=0; for(int i=0;i<zi.length;i++) { sum+=zi[i].getNum(); } return sum; }
综上所述,整体思路是:在二维整形数组中,数据可能会有正也有负,要求最大值,我们重点关注正数,所以要首先判断二维数组中哪些位置上的数是正数,利用另一个二维数组记录正数的位置,然后判断哪些数是连通的。
首先定位这个二维数组中的最大值,然后在分析这个值周围的4个数,联通这4个数中的正数,若全为负数,则放弃这个正数,向下遍历;若有正数,则连通,再判断新联通的周围是否有值得连的数,以此类推,直到最大联通子数组怎么联通都比原来的值小。
虽然这次的题目没有完成,但我们已经懂得如何将问题分解,分解为简单的分块,然后一点点解决的思路,并且一开始打算按照图的方向思考,将沉淀许久的数据结构思想重拾起来,所以,收获还是大大滴!!!但这个程序我们不会放弃,仍在努力完成中......
第七周学习进度条: