毎日1つのアルゴリズムシリーズ(32)を勉強します(1つのマトリクスの中で最大の2次元マトリクス(要素と最大)を求めます)
3330 ワード
タイトル:
1つの行列の中で最大の2次元の行列(要素と最大)を求めます.例えば:1 2 0 3 4 2 4 4 5 1 1 5 3 0の中で最大の2次元行列は:4 5 3
要求:(1)アルゴリズムを書く;(2)分析時間の複雑さ;(3)Cでキーコードを書く.
構想1:この問題は最大の2次元行列を要求して、私達のまず思い付く1つの解法は:行1から行Nまで遍歴して、2次元行列を単位として遍歴して、すなわち、(行x列x--行x+1列x+1)は1単位で遍歴し、遍歴の過程でその行列の和値を記録し、最大和値と比較し、最大の2次元行列と値に対応する行列値を遍歴が終わるまで保存し、最大の2次元行列を見つけることができる.Ncolが表す行列の列数.
コードは次のとおりです.
拡張:もしテーマが最大のサブマトリクスを求めることを要求するならば、私たちはマトリクスの垂直方向の配列を1つの要素と見なすことができます.したがって,行列は我々がよく知っている1次元配列に変換された.すなわち、以上の行列は、a[1->n][1]a[1->n][2]...a[1->n][i] .. a[1->n][j] .. a[1->n][n]1->nは垂直方向を表し、a[1->n][1]は第1列のすべての要素が加算された値を表す.では、5 X 5行列と仮定すると、その解法は、第1行:a[1-5][1]a[1-5][2]a[1-5][3]a[1-5][4]a[1-5][5]が1次元配列を形成し、その配列の最大和値はSum 1である.
2行目:a[2-5][1]a[2-5][2]a[2-5][3]a[2-5][4]a[2-5][5]は、Sum 2の最大和値を有する1次元配列を形成する.
3行目:a[3-5][1]a[3-5][2]a[3-5][3]a[3-5][4]a[3-5][5]は、Sum 3の最大和値を持つ1次元配列を形成する.
4行目:a[4-5][1]a[4-5][2]a[4-5][3]a[4-5][4]a[4-5][5]は1次元配列を形成し、この配列の最大和値はSum 4である.
第5行:a[5][1]a[5][2]a[5][3]a[5][4]a[5][5]は一次元配列を形成し、この配列の最大和値はSum 5である.
次に、Sum 1~Sum 5を比較する最大値が、その行列の最大サブ行列に対応する和であることを見出す.
1つの行列の中で最大の2次元の行列(要素と最大)を求めます.例えば:1 2 0 3 4 2 4 4 5 1 1 5 3 0の中で最大の2次元行列は:4 5 3
要求:(1)アルゴリズムを書く;(2)分析時間の複雑さ;(3)Cでキーコードを書く.
構想1:この問題は最大の2次元行列を要求して、私達のまず思い付く1つの解法は:行1から行Nまで遍歴して、2次元行列を単位として遍歴して、すなわち、(行x列x--行x+1列x+1)は1単位で遍歴し、遍歴の過程でその行列の和値を記録し、最大和値と比較し、最大の2次元行列と値に対応する行列値を遍歴が終わるまで保存し、最大の2次元行列を見つけることができる.Ncolが表す行列の列数.
コードは次のとおりです.
/*-----------------------------
Copyright by yuucyf. 2011.08.25
------------------------------*/
#include "stdafx.h"
#include <assert.h>
#include <iostream>
using namespace std;
typedef struct tagMatrixInfo
{
int i32nLine;
int i32nCol;
tagMatrixInfo()
{
i32nLine = i32nCol = 0;
}
}S_MatrixInfo;
S_MatrixInfo GetMax2X2Matrix(int **ppMatrix, int nLine, int nCol)
{
assert(ppMatrix);
assert(nLine >= 2);
assert(nCol >= 2);
S_MatrixInfo sMaxMatrixInfo;
int nMaxValue = 0, nTempValue = 0;
for (int i32I = 0; i32I < nLine - 1; i32I++)
{
for (int i32J = 0; i32J < nCol - 1; i32J++)
{
nTempValue += (ppMatrix[i32I][i32J] + ppMatrix[i32I][i32J+1]);
nTempValue += (ppMatrix[i32I+1][i32J] + ppMatrix[i32I+1][i32J+1]);
if (nTempValue > nMaxValue)
{
nMaxValue = nTempValue;
sMaxMatrixInfo.i32nLine = i32I;
sMaxMatrixInfo.i32nCol = i32J;
}
nTempValue = 0;
}
}
return sMaxMatrixInfo;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i32I = 0, i32J = 0;
int i32nLine = 0, i32nCol = 0;
cin >> i32nLine >> i32nCol;
int **ppMatrix = new int *[i32nLine];
assert(ppMatrix);
for (i32I = 0; i32I < i32nLine; i32I++)
{
ppMatrix[i32I] = new int[i32nCol];
assert(ppMatrix[i32I]);
for (i32J = 0; i32J < i32nCol; i32J++)
{
cin >> ppMatrix[i32I][i32J];
}
}
S_MatrixInfo sMaxMatrixInfo = GetMax2X2Matrix(ppMatrix, i32nLine, i32nCol);
cout << endl << " :" << endl;
for (i32I = sMaxMatrixInfo.i32nLine; i32I < sMaxMatrixInfo.i32nLine + 2; i32I++)
{
for (i32J = sMaxMatrixInfo.i32nCol; i32J < sMaxMatrixInfo.i32nCol + 2; i32J++)
{
cout << ppMatrix[i32I][i32J] << " ";
}
cout << endl;
}
return 0;
}
拡張:もしテーマが最大のサブマトリクスを求めることを要求するならば、私たちはマトリクスの垂直方向の配列を1つの要素と見なすことができます.したがって,行列は我々がよく知っている1次元配列に変換された.すなわち、以上の行列は、a[1->n][1]a[1->n][2]...a[1->n][i] .. a[1->n][j] .. a[1->n][n]1->nは垂直方向を表し、a[1->n][1]は第1列のすべての要素が加算された値を表す.では、5 X 5行列と仮定すると、その解法は、第1行:a[1-5][1]a[1-5][2]a[1-5][3]a[1-5][4]a[1-5][5]が1次元配列を形成し、その配列の最大和値はSum 1である.
2行目:a[2-5][1]a[2-5][2]a[2-5][3]a[2-5][4]a[2-5][5]は、Sum 2の最大和値を有する1次元配列を形成する.
3行目:a[3-5][1]a[3-5][2]a[3-5][3]a[3-5][4]a[3-5][5]は、Sum 3の最大和値を持つ1次元配列を形成する.
4行目:a[4-5][1]a[4-5][2]a[4-5][3]a[4-5][4]a[4-5][5]は1次元配列を形成し、この配列の最大和値はSum 4である.
第5行:a[5][1]a[5][2]a[5][3]a[5][4]a[5][5]は一次元配列を形成し、この配列の最大和値はSum 5である.
次に、Sum 1~Sum 5を比較する最大値が、その行列の最大サブ行列に対応する和であることを見出す.