zoukankan      html  css  js  c++  java
  • Task 4.2 求一个矩阵的最大子矩阵的和

    任务:输入一个二维整形数组,数组里有正数也有负数。二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。

    (1)设计思想:把二维矩阵分解成行、列的情况,可以相应把问题简化。之后分别依照行和列的基准来求每一个矩阵的和,再依次进行比较每个矩阵的和。最容易想到也是最容易实现的方法。遍历矩阵(行迭代器为i,列迭代器为j),以当前遍历到的元素为首a[i,j],计算二维子矩阵的和(sum=a[i,j]+a[i+1,j]+a[i,j+1]+a[i+1,j+1]),并找出和最大的二维矩阵,注意矩阵的最后一行和最后一列不用遍历。时间复杂度为O(i*j)。

    改进方法如下:

    a.原先每次访问四个元素,现在变为每次访问纵向的两个元素(a[i,j],a[i+1,j]),横向遍历,遍历的起始点改为第二个元素,终点到最后一个元素。

    b.改变求和方式,求和方法是:首先将上一次保存的和last_vsum加进sum中,再将last_vsum更新为当前纵向的两个元素a[i,j],a[i+1,j]之和,然后再将last_vsum加入sum中,这样就得到本次二维矩阵的和可与maxsum进行比较。如此每次求和只需访问两个元素a[i,j],a[i+1,j]。

    (2)代码:

    #include<iostream>
    #include<time.h>
    using namespace std;
    
    void main()
    {
        int m,n,a[100][100],k,t,c,i,j,z;
        int maxsum,sum[100],max=0;
        cout<<"请输入矩阵的行数和列数:"<<endl;
        cin>>m>>n;
        srand((unsigned)time(NULL));
        for(i=0;i<m;i++)
         {   
             for(j=0;j<n;j++)
             {
                 a[i][j] = rand() %140 - 70;
                 cout<<a[i][j]<< " ";
             }
             cout<<endl;
         }
            for(k=0;k<m;k++)
            {
                //初始化一个m*n型的二维数组,以作为储备每一个细化的子矩阵之和
                for(c=0;c<n;c++)
                {sum[c]=0;}
                //求此矩阵划分而得的每一个子矩阵之和
                for(j=k;j<n;j++)
                {
                    for(i=0;i<m;i++)
                    {
                        sum[i]+=a[i][j];
                    }
                    //依次比较所得到的每个子矩阵之和取最大子矩阵之和
                       for(t=0;t<m;t++)
                       {
                        maxsum=0;
                        for(z=t;z<n;z++)
                        {
                            maxsum+=sum[z];
                            if(maxsum>max)
                                max=maxsum;
                        }
                       }
                }
            }
           cout<<"最大子矩阵之和为:"<<max;
     
      
    }


    3.实验截图:

    4.总结:(1)开始上课的时候就在找各种方法实现,比如找到矩阵中的最大和再扩展开求最大矩阵和;或是找出所有正数根据正数的个数和大小判断求出最大矩阵和;但是最终都没有得出一个完整的思路,因为都太难实现了而且总会有一些细节与期望值不相符。所以最后我们两个就重整思路写出了这个程序。

    (2)要学会把一个复杂的项目分解,因为只有学会了分解以后才能更快更好地解决所有的问题。

  • 相关阅读:
    C++操作mysql方法总结(3)
    C++操作mysql方法总结(2)
    C++操作mysql方法总结(1)
    基于C++11的线程池
    C++ 类之间的互相调用
    C++编译与链接(1)-编译与链接过程
    C++判断char*的指向
    确保你想要修改的char*是可以修改的
    C++编译与链接(0)-.h与.cpp中的定义与声明
    C++获取private的变量-偷走private
  • 原文地址:https://www.cnblogs.com/mengxiangjialzh/p/4404191.html
Copyright © 2011-2022 走看看