首页 > 代码库 > 二维数组求最大连通子数组的和

二维数组求最大连通子数组的和

题目:返回一个二维整数数组中最大联通子数组的和。

要求: 输入一个二维整形数组,数组里有正数也有负数。 求所有子数组的和的最大值。

程序要使用的数组放在一个叫 input.txt 的文件中, 文件格式是: 数组的行数, 数组的列数, 每一行的元素, (用逗号分开) 每一个数字都是有符号32位整数,当然,行数和列数都是正整数。

 

源程序

/*
 设计思路:
1、首先从文件读入一个二维整型数组(有正有负);
2、从数组中选出最小的一个数,如果为负数则除去,检验联通性;
3、联通,接下来找剩余中最小的数,如果为负数则除去,检验联通性;如果为正数,则可得最大的和。
4、如果在检验联通性时不成立,则保存最近的联通数组的和。
5、循环执行第3步,直到保存了所有可能的联通数组的和,找出最大值。
*/

package zishuzu1;

import java.io.*;

public class zishuzu1 {
    static int b=52345;
    static int[][] p= new int[100][100];  
    public static void main(String[] args) throws IOException {
          
        File f = new File("input.txt");  
        BufferedReader buf = new BufferedReader(new FileReader(f));  
        int temp=0,line = 0;  
        String str;
        System.out.println("数组:");
        int m=Integer.parseInt(buf.readLine());//行
        int n=Integer.parseInt(buf.readLine());//列
        while ((str=buf.readLine()) != null) 
        {   
            String[] data = http://www.mamicode.com/str.split(","); 
            for (int i = 0; i < data.length; i++) 
            {  
                 p[line][i] = Integer.parseInt(data[i]);  
                 if(temp!=line)
                 {
                     temp=line;
                     System.out.println();
                 }
                 System.out.print(p[line][i]+"  "); 
            }
            line++;  
        }
        System.out.println();
        
        int []a=new int [100];//保存和
        int []aa=new int [100];//保存去掉的使不连通的数
        int h=0,t=0,s=a[0],s1=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(min(m,n)<0)
                {
                    a[h]=sum(m,n);
                    aa[t]=qmin(m,n);
                    h++;
                    
                    if(liantong(m,n)==true)
                        continue;
                    else
                    {
                        t++;
                        continue;
                    }
                    
                }
                else
                {
                    System.out.println("最大联通子数组的和:"+sum(m,n));
                    i=m;
                    break;
                }
                
            }
        }
        for(int d=0;d<h;d++)
        {
            if(a[d+1]>=a[d])
                s=a[d+1];
        }
        for(int d=0;d<t-1;d++)
        {
            System.out.println(aa[d]);
            s1=s1+aa[d];
        }
        int result =s+s1;
        System.out.println("最大联通子数组的和:"+result);

    }
    public static boolean liantong(int m,int n)
    {
        int k=0; 
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(i==0&&j==0) 
                {
                     if(p[i+1][j]==b&&p[i][j+1]==b)
                         k=-1;
                }
                else if(i==m-1&&j==n-1)
                {
                     if(p[i-1][j]==b&&p[i][j-1]==b)
                         k=-1;
                }
                else if(i==0&&j==n-1)
                {
                    if(p[i+1][j]==b&&p[i][j-1]==b)
                         k=-1;
                }
                else if(i==m-1&&j==0)
                {
                    if(p[i-1][j]==b&&p[i][j+1]==b)
                         k=-1;
                }
                else if(i==0&&j!=0)
                {
                     if(p[i+1][j]==b&&p[i][j+1]==b&&p[i][j-1]==b)
                         k=-1;
                }
                else if(i!=0&&j==0)
                {
                     if(p[i+1][j]==b&&p[i-1][j]==b&&p[i][j+1]==b)
                         k=-1;
                }
                else if(i!=0&&i!=m-1&&j!=0&&j!=n-1)
                {
                     if(p[i+1][j]==b&&p[i-1][j]==b&&p[i][j+1]==b&&p[i][j-1]==b)
                         k=-1;
                }
            }
        }
        if(k==-1) return false;
        else return true;
    }
    public static int min(int m,int n)
    {  
        int minz=p[0][0];
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(p[i][j]!=b&&p[i][j]<minz)
                {
                    minz=p[i][j];
                }
            }
        }
        return minz;
    }
    public static int sum(int m,int n)
    {
        int sumz=0; 
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(p[i][j]!=b)
                {
                    sumz=sumz+p[i][j];
                }
            }
        }
        return sumz;
    }
    public static int qmin(int m,int n)
    {  
        int w=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(min(m,n)==p[i][j])
                {
                    w=p[i][j];
                    p[i][j]=b;
                    i=m;
                    break;
                }
            }
        }
        return w;
    }
    
}

结果截图

技术分享技术分享

然而此程序还有小bug有待改进,还未成功。

 

结对成员(刘玉,陈孜洋)

编程过程中遇见很多思路的问题,两人相互讨论,得出都认可的解决方法。效率也提高了。

二维数组求最大连通子数组的和