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

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

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

程序要使用的数组放在一个叫 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 = 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有待改进,还未成功。

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

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

时间: 2024-10-08 15:32:47

二维数组求最大连通子数组的和的相关文章

返回一个二维数组中最大联通子数组的和

1 #include <iostream> 2 #include <time.h> 3 #include<string> 4 #include<fstream> 5 #define M 3 6 #define N 4 7 using namespace std; 8 9 int main() 10 { 11 int length[100],num[M][N] = {0},visit[M][N]={0},i=0;//length[100],是把文件中的数组转化

二维数组最大和的子数组的和

设计思想: 首先肯定是把二维转化为一维数组来比较,这样,先从第一行开始,把第一行看成是一维数组选出最大子数组具体实现是,设子数组和为sum=0,另设b=0,a[0][i]从a[0][0]开始检索当b<0时b=a[0][i]否则b=b+a[0][i]只有当b>sum时sum=b,(首先保证sum的初次赋值是大于0然后就是对b的操作首次出现正数时赋给b此时sum=0,b>sum,所以sum=b,然后继续上一步对b的正负性的判断分解为,开始由上一步b>0所以b=b+a[0][i],若a[

数组练习3 求最大连通子数组的和

一.题目要求 1.返回一个二维整数数组中最大连通子数组的和. 二.设计思路 刚开始看到这个题目时,想了应该对其降维,然后再一维数组的基础上解决问题更方便,但是一直想不到办法,然后在老师的指导下,想到了离散和数据结构曾经学到的有关图的联通的解决办法,将二维数组看成一个图来遍历来寻找最大子数组的和. 本次实验,老师要求从文件中读入行和列还有数组元素,我们利用fstream实现从文件的读入,一次读入行列和数组元素. 本次实验我们没有能实现有符号的32位整数的大数的运算,实验完成度没有达到要求. 三.程

二维数组求子数组之和最大值(首尾相接, 圆柱)

问题:求二维数组的子数组之和的最大值(首尾相接,即形成圆柱) 成员: 陈晨:负责代码复审和代码测试计划 王颖瑞:负责程序分析,代码编程 思路:对于这个问题,我们可以结合之前的实验(二维数组求子数组之和的最大值和首尾相连一维数组的子数组之和的最大值),把为二维数组的列扩大二倍,之后想一维数组(首尾相连)一样,把二维数组分成不同的几个二维数组.之后就分开求不同的二维数组的子数组的最大值,最后之间比较,求出总的最大值. 代码: #include<iostream> using namespace s

体验结对开发的乐趣(5)--(首尾相连的二维数组求最大子数组和的问题)

结对伙伴:信1201-2班高扬.信1201-1班韩雪东 一.题目要求与设计思想 题目要求:在上一次的基础上把数组变为二维数组,然后首尾相接,形成连环,然后求和最大的子数组: 设计思想:一维数组首尾相连的问题已经得到解决,二位数组求和最大的子数组的问题也已经解决了,就是把这两个程序思想融在一起,然后在短短的时间内就完成了这次课堂项目. 二.源代码 1 // erweishuzuqiuzuida.cpp : Defines the entry point for the console applic

二维数组求最大子数组

设计思路: 首先定义产生二维数组,定义可输入二维数组行和列,各位数随机产生: 然后进行最大子数组的求和比较,从每行的第一个数为子数组的起点开始进行不同的子数组遍历比较,只存放最大的子数组,以及记录最大子数组的位置,从第一个数开始每行每列进行求和比较,以求得最大子数组的值,以及最大子数组所包含的数: 最后进行结果的输出与验证. 代码: 法一: package zishuzu; import java.util.*; public class zuixiaozishuzu { public stat

软件工程个人作业05(二维数组求最大子数组的和)

题目:返回一个二维整数数组中最大联通子数组的和. 要求:输入一个二维整形数组,数组里有正数也有负数.求所有子数组的和的最大值.要求时间复杂度为O(n). 程序要使用的数组放在一个叫 input.txt 的文件中, 文件格式是: 数组的行数, 数组的列数, 每一行的元素, (用逗号分开) 每一个数字都是有符号32位整数,当然,行数和列数都是正整数.程序设计思路:此次试验考虑到需要求最大联通子数组和.可以定义一个类(其中有value,x,y,neighbor,select),主函数里定义一个二维的对

二维数组求最大子数组和(环形)

一.实验题目 返回一个二维数组中最大子数组的和. 实验要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.实验思路 这次我们设计的实验是手动输入二维数组的行数和列数,二维数组的环形求和我们设计的思路和一位数组的类似,就是把求完的数组的第一列放到最后,依次类推.求最大的子数组和时和二维数组的求和类似,即:输入的二维数组是 -1 

二维数组求最大值

设计思想:      首先要用一段代码,可以读入txt文件里的二维数组.需要将txt文件放入同一目录.       其次要用一段代码得到最大子数组的和:主要思路与求一维数组方法相差不多,不过要有更多的循环和判断汲取了先者的成果,我们得出了方法.思路如下: 1.得到子数组的最大行.列数,从第一行开始,确定最大子数组的行列范围. 2.将确定的范围,把最大子数组按照一列有几个数,按行分开成.(例如第一个组中只有一行,而第二个组中有两行,列数和数组的列数保持一致) 3,对2中得到的数组,利用一维数组求子