一维,环状,二维数组最大连续子数组和

(一)一维最大连续子数组和

解法思路:在一段数组中,以每个数组下标为末尾的最大连续子数组,判断前一个连续数组和是否大于0,大于就可以加上该数构成一个更大的连续子数组;否则,自己组成一个连续数组。最后,遍历整个数组找出最大值。

#include
#include
using namespace std;
const int N=100000;
int main()
{
    int i,j,k;
    int a[N];
    int sum[N];
    int n;
    printf("请输入数组个数:\n");
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    sum[1]=a[1];
    int maxn=sum[1];
    for(i=2;i<=n;i++)
    {
        if(sum[i-1]>0)
            sum[i]=a[i]+sum[i-1];
        else
            sum[i]=a[i];
        maxn=max(maxn,sum[i]);
    }
    cout<endl;
    return 0;
}

(二)环状数组求最大连续子数组和

解法:环状数组出现最大连续子数组和的范围有两个:

①在a[0]~a[n]之间出现最大的连续子数组

②包含a[n]~a[0]形成最大的连续子数组

那面对第一种的解法我们就是按照普通的数组来进行处理

对于第二种的解法,我们可以用逆向思维来进行考虑,既然最大的会包含a[n]~a[0],那么最小连续区间应该是在a[0]~a[n]范围内的,因此只要我们找出最小连续区间的末位置,以此开始作为起点来进行普通数组的处理就可以找到第二种解法的答案。

最后比较这两种解法哪个值最大,那么他就是环状数组最大连续子数组的和

#include
#include
using namespace std;
int n;
int NotCircle(int a[])
{
    int maxn=-1000;
    int sum[10000];
    sum[0]=a[0];
    for(int i=1;i)
    {
        if(a[i]1])
        {
            sum[i]=a[i]+sum[i-1];
        }
        else
        {
            sum[i]=a[i];
        }
        if(maxn<sum[i])
            maxn=sum[i];
    }
    return maxn;
}

int findmin(int a[])
{
    int minx=10000000;
    int sum[10000];
    int flag=0;
    sum[0]=a[0];
    for(int i=1;i)
    {
        if(sum[i-1]<0)
            sum[i]=sum[i-1]+a[i];
        else
            sum[i]=a[i];
        if(minx>sum[i])
        {
            minx=sum[i];
            flag=i;
        }
    }
    return flag;
}

int Circle(int a[])
{
      int minid=findmin(a);
      int key=(minid+1)%n;
      int j;
      int maxn=a[key];
      int sum=0;
      for(j=key;(j%n)!=minid;j++)
      {
          if(sum>0)
            sum+=a[j%n];
        else
            sum=a[j%n];

          if(maxn<sum)
            maxn=sum;
      }
      return maxn;
}

int main()
{
    int a[100],i,j;
    cin>>n;
    for(i=0;i)
        cin>>a[i];
    int ans1=NotCircle(a);
    int ans2=Circle(a);
    cout<" "<endl;
    int ans=max(ans1,ans2);
    cout<<ans;
    return 0;
}

(三)二维数组的最大子数组和

这个是一维数组的升级版,他的做法是先处理每一行,然后再对每一列进行处理,处理时按“两列”“三列”。。。“C列”处理,最后就可以找到最大值。

行为r,列为c,数组为随机生成的

package test;

import java.util.Random;
import java.util.Scanner;

public class test01 {

    public static void main(String[] args) {
        // TODO 自动生成的方法存根
        Scanner in=new Scanner(System.in);
        System.out.println("输入要随机生成的行数!");
        int r=in.nextInt();
        System.out.println("输入要随机生成的列数!");
        int c=in.nextInt();
        int a[][]=new int[r][c];
        int i,j,k,p,q;
        for(i=0;i)
        {
            for(j=0;j)
            {
                Random random=new Random();
                a[i][j]=random.nextInt(11);
                a[i][j]-=1;
                System.out.print(a[i][j]);
                System.out.print(" ");
            } 
            System.out.println();
        }
        int sum=0,n;
        int maxn=0;
        //先计算单个行的最大值
        //接着单列每2个组合到一起的最大值
        //接着单列每3个组合到一起的最大值
        //...一直到单列每r个组合到一起的值
        //找出他们的最大值。
        for(n=0;n)
        {
            for(i=0;i)
            {
                sum=0;
                for(j=0;j)
                {
                    for(k=i;k<=i+n;k++)
                    {
                        System.out.println(k+","+j);
                        sum=sum+a[k][j];
                    }
                    System.out.println(sum+" ");
                    if(sum<0)
                    {
                        sum=0;
                    }
                    if(maxn<sum)
                    {
                        maxn=sum;
                    }
                }
            }
        }
        System.out.println(maxn);
    }
}

(四)一维数组续集

一维,环状,二维数组最大连续子数组和_第1张图片

 

 对于这种新情况的处理,首先对于数的溢出,我用的是java.math里的BigInteger来储存最大的连续子数组和

其次对于文件中的不符合的参数爆出相应的错误,允许输入的有“数字”,“-”“,”。

错误输入分类:

①没有该文件

②文件为空

③有不合法的输入:例如(汉字,字母符号等等)

package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Scanner;

public class test02 {

    public static void main(String[] args) throws IOException {
        // TODO 自动生成的方法存根
        Scanner in=new Scanner(System.in);
        String fileName ="E:\\target.txt";
        File file=new File(fileName);
        System.out.println(file.length());
        if(!file.exists()) {
            System.out.println("文件不存在!");
        }else if(file.exists() && file.length() == 2) {
            System.out.println("文件为空!");
        }
        else {
            FileReader fileReader = new FileReader(fileName);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String line;
            int i,j;
            int flag=0;
            BigInteger ans=new BigInteger("0");
            BigInteger maxn=new BigInteger("0");
            while ((line=bufferedReader.readLine())!=null){
                String []s=line.split(",");
                for(i=0;i)
                {
                    String k=s[i];
                    for(j=0;j)
                    {
                        if(!((k.charAt(j)>='0'&&k.charAt(j)<='9')||k.charAt(j)=='-'||k.charAt(j)==','))
                        {
                            System.out.println("文件输入不合法,必须全部由数字组成,中间分割用逗号!");
                            flag=1;
                            break;
                        }
                    }
                    BigInteger key=new BigInteger(k);
                    BigInteger cmp=new BigInteger("0");
                    if(key.subtract(cmp).intValue()>0)
                        ans=ans.add(key);
                    else
                        ans=key;
                    if(ans.subtract(maxn).intValue()>0)
                        maxn=ans;
                    if(flag==1)
                        break;
                }
                if(flag==1)
                    break;
            }
            if(flag==0)
                System.out.println(maxn);
            bufferedReader.close();
            fileReader.close();
        }
    }
}

 

你可能感兴趣的:(一维,环状,二维数组最大连续子数组和)