求和最大的子矩阵

/* 求一个矩阵中最大的二维矩阵(元素和最大).如: 
1 2 0 3 4 
2 3 4 5 1 
1 1 5 3 0 
中最大的是: 
4 5 
5 3 
*/  
#include <limits>  
// 假设寻找的子矩阵是大小为n的方阵,不限于二维。  
// 先对行求和,得到矩阵sumMat[row-n+1][col],里面每个元素都对应了n行的和
// 然后对sumMat的每行求最大的子序列(长度为n)

// 子函数,预处理,对原始矩阵的行求和,输出辅助矩阵
static  void addRow( const vector<vector< int> >& m, int n, vector<vector< double> >& sumMat) 
{
     int row = ( int)m.size();
     int col = ( int)m[ 0].size();
    sumMat.resize(row-n+ 1,vector< double> (col));

     for( int i= 0; i < n; ++i)
    {
         for( int j= 0; j < col;++j)
        {
            sumMat[ 0][j] += m[i][j];
        }
    }

     int idx =  0;
     for( int end= n; end < row; ++end)
    {
         for( int j= 0; j < col;++j)
        {
             // 注意下标
            sumMat[idx+ 1][j] = sumMat[idx][j] + m[end][j] - m[end-n][j];
        }
        idx++;
    }
}
// 子函数,对每行计算最大序列的位置
static  void calcMax( const vector< double>& sumArrary, int n, int &col,  double& sum)
{
    sum= 0;
    col =  0;
     for( int i= 0; i < n; ++i)
    {
        sum+= sumArrary[i];
    }

     double max= sum;
     for( int i= n; i < sumArrary.size(); ++i)
    {
        sum += sumArrary[i] - sumArrary[i-n];
         if(sum > max)
        {
            col = i-n+ 1// 注意是返回子序列的起始位置
            max = sum;
        }
    }
    sum = max;
}

bool calcMaxSubMatrix( const vector<vector< int> >& m, int n, double& sum, vector<vector< int> >& subMat) 
{
     int row = ( int)m.size();
     int col = ( int)m[ 0].size();
     if(n > row || n > col){ return  false;}  

    vector<vector< double> > sumMat;
    addRow(m,n,sumMat);  // 预处理

     double max= -DBL_MAX;
     int maxCol, maxRow;
     for( int i= 0; i < sumMat.size(); ++i)
    {
         int col;
         double matSum;
        calcMax(sumMat[i],n,col,matSum);
         if(matSum > max)
        {
            max = matSum;
            maxCol = col;
            maxRow = i;
        }
    }

    sum = max;
    subMat.resize(n, vector< int> (n));    
     for( int i = 0; i < n; ++i)    
    {    
         for( int j = 0; j < n; ++j)    
        {    
            subMat[i][j] = m[maxRow+i][maxCol+j];    
        }    
    }    
        
     return  true;  
}

static  void fillVector( int* a, int row,  int col, vector<vector< int> >&  out)    
{    
     out.resize(row, vector< int> (col));    
     for( int i= 0 ; i < row; ++i)    
    {    
         for( int j= 0; j < col; ++j)    
        {    
             out[i][j] = a[i*col+j];    
        }    
    }    
}   
static  void test1()    
{    
    vector<vector< int> > m;    
     int a[ 3][ 5] ={  { 12034},
                    { 23451},
                    { 11530}};    
    fillVector(a[ 0], 3, 5,m);    
        
    vector<vector< int> > subM;    
     double sum;    
    calcMaxSubMatrix(m, 2,sum,subM);    
    printf( " sum=%g\n ",sum);    
     for(size_t i= 0 ; i < subM.size(); ++i)    
    {    
         for(size_t j= 0; j < subM[i].size(); ++j)    
        {    
            printf( " %d, ", subM[i][j]);    
        }    
        printf( " \n ");    
    }    
}   

static  void test2()    
{    
    vector<vector< int> > m;    
     int a[ 3][ 5] ={{ 12034},{ 23451},{ 1153, 10}};    
    fillVector(a[ 0], 3, 5,m);    
        
    vector<vector< int> > subM;    
     double sum;    
    calcMaxSubMatrix(m, 2,sum,subM);    
    printf( " sum=%g\n ",sum);    
     for(size_t i= 0 ; i < subM.size(); ++i)    
    {    
         for(size_t j= 0; j < subM[i].size(); ++j)    
        {    
            printf( " %d, ", subM[i][j]);    
        }    
        printf( " \n ");    
    }    
}    
void testCalcMaxSubMatrix()    
{    
    test1();    
    test2();    
}   

转载于:https://www.cnblogs.com/pop-lar/p/4194844.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值