二维数组的最大子数组和 时间复杂度:O(n的四次方)

时间:2021-12-19 09:24:15

先上代码

小组成员:高达,李奔

二维数组的最大子数组和 时间复杂度:O(n的四次方)

package 三月二十一号;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern; public class Main1 { public static void main(String[] args) {
// TODO 自动生成的方法存根 //读取
int max=0;
int sum=0;
String b="E:\\大二\\软件工程\\java\\src\\三月二十一号\\input.txt";
ArrayList<String> list1 = new ArrayList<String>();
list1=wenjian(b);
//转化为数字数组
ArrayList<Integer> list = new ArrayList<Integer>();
list=String_To_Integer(list1);
//获取行数与列数
final int LINENUMBER=list.get(0);
final int COLUMN_NUMBER=list.get(1);
// System.out.println(LINENUMBER);
// System.out.println(COLUMN_NUMBER);
int a[]=new int[COLUMN_NUMBER];
//几行求解
for(int i1=1;i1<=LINENUMBER;i1++)
{
//N1-i1+1次
for(int i2=1;i2<=LINENUMBER-i1+1;i2++)
{ //给数组赋值
for(int j=0;j<COLUMN_NUMBER;j++)
{
for(int i3=0;i3<i1;i3++)
{
a[j]=a[j]+list.get((i2-1)*COLUMN_NUMBER+j+2+i3*COLUMN_NUMBER);
//System.out.println(a[j]);
}
}
//求这行的最大值
sum=max_int_Array(a);
//System.out.println(sum);
//比较
if(max<sum)
{
max=sum; }
//重置数组a
for(int i=0;i<a.length;i++)
{
a[i]=0;
}
}
} System.out.println(max);
}
//求一行
static Integer max_int_Array(int a[])
{
Integer sum=0;
Integer max=0;
for(int i=0;i<a.length;i++)
{
sum=sum+a[i];
if(sum<0)
{
sum=0;
}
if(sum>max)
{
max=sum;
}
}
if(sum==0)
{
max=a[0];
for(int i=1;i<a.length;i++)
{
if(max<a[i])
{
max=a[i];
}
}
}
return max; }
/*之前的代码但是还是觉得int[]好用
//求一行
static Integer max_int_Array(ArrayList<Integer> b)
{
Integer sum=0;
Integer max=0;
for(int i=0;i<b.size();i++)
{
sum=sum+b.get(i);
if(sum<0)
{
sum=0;
}
if(sum>max)
{
max=sum;
}
}
if(sum==0)
{
max=b.get(0);
for(int i=1;i<b.size();i++)
{
if(max<b.get(i))
{
max=b.get(i);
}
}
}
return max; }
*/
//转化成整数数组
public static ArrayList<Integer> String_To_Integer(ArrayList<String> list)
{
ArrayList<Integer> list1 = new ArrayList<Integer>();
for(int i=0;i<list.size();i++)
{
Integer integer =new Integer(list.get(i));
list1.add(integer);
}
return list1; }
//读取
public static ArrayList<String> wenjian(String b)
{
ArrayList<String> list = new ArrayList<String>();
boolean flag=true;
try // 建立一个对象,它把文件内容转成计算机能读懂的语言
{
Scanner shuru = new Scanner(new BufferedReader(new FileReader(b)));
String a;
//网友推荐更加简洁的写法
while ((shuru.hasNext()) ) {
// 一次读入一行数据
a=shuru.next();
if(isNumeric(a))
{
list.add(a);
}
else
{
flag=false;
} }
shuru.close();
} catch (IOException e) { e.printStackTrace();
}
if(flag==true)
{
return list;
}
else
{
System.err.println("文件格式有错误,退出");
return null;
}
}
//判断是不是数字
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("-[0-9]+(.[0-9]+)?|[0-9]+(.[0-9]+)?");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
}

成功结果:二维数组的最大子数组和 时间复杂度:O(n的四次方)

我和我小组成员的思路是:

我(高达)提出的:建一个类来封装一行的一维正块,然后根据一维正块上下求索正块矩形,比较出最大值。时间复杂度:O(n的三次方)

但是逻辑上很难实现,做不了。

上课的时候有人说就是一行比然后俩行比然后三行比依次类推求出最大,然后我们就是使用的这种方法。时间复杂度:O(n的四次方)

实验过程:

先使用ArrayList<String>存储取出来的数字,存储的时候用正则来判断是否为数字,然后转化为ArrayList<Integer>存储,List的第一个是行数,第二个是列数,然后逻辑上2号位是第一个数字。

这个问题的解决关键是

1.理清关系,上下差一个列数。

2.当一行比的时候比n次,俩行比n-1次……n行比1次。

实验时遇到的问题:

方法意见不统一,我和小组成员有分歧,我一直坚持我的那种思路,但是我们认为实现起来太难了。

代码实现时的逻辑出现了俩次错误,i1 i2 i3 j   i3和j的关系  i2和i1的使用  为啥出错我们自己的逻辑错误。

实验用时:

三小时(讨论+写代码+改代码)