矩阵最大的N数字的最大产品
Matrix largest product of n numbers in a row
您好,我在尝试编写一个小程序时遇到了麻烦。问题是,如果我给出了任何矩阵大小(在此示例中只能说一个4x4),请连续找到最大的n个数字产品(假设n = 3)。一行的3个数字可以是水平,垂直或对角线。所以这是一个矩阵:
1 1 2 5
1 5 2 4
1 7 2 3
1 8 2 1
如果N等于3,则我最大的产品将为280(5*7*8)。现在,我将矩阵加载到2D向量中。我对程序的工作原理不太挑剔(蛮力很好),到目前为止,我知道我必须至少有两个嵌套以遍历矩阵的每个凝视地点,但是我还没有成功找到当前答案。任何建议都会有所帮助,谢谢。
版本,使用滚动乘法在行中找到最大产品以节省一些资源。此滚动过程意味着我们不必乘以n
值即可找到这些n
值的每个产品,但是我们只需要做一个乘法和一个一个 discriplication:
if (currN == N) { // compute full product first time
while (currn) {
product *= (*it3++);
--currn;
}
} else { // rolling computation
product *= (*(it3 + n - 1)) / (*(it3 - 1));
it3 += n;
}
由您完成此操作以处理列:
填充矩阵:
#include <cstdio>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
typedef vector< vector< int> > Matrix;
typedef Matrix::iterator outIt;
typedef vector< int>::iterator inIt;
void fillMatrix( Matrix& matrix) {
outIt it = matrix.begin();
(*it).push_back( 1);
(*it).push_back( 1);
(*it).push_back( 2);
(*it).push_back( 5);
++it;
(*it).push_back( 1);
(*it).push_back( 5);
(*it).push_back( 2);
(*it).push_back( 4);
++it;
(*it).push_back( 1);
(*it).push_back( 7);
(*it).push_back( 2);
(*it).push_back( 3);
++it;
(*it).push_back( 1);
(*it).push_back( 8);
(*it).push_back( 2);
(*it).push_back( 1);
}
打印矩阵并在行中找到最大产品:
void printMatrix( Matrix& matrix) {
outIt it = matrix.begin();
while ( it != matrix.end()) {
inIt it2 = (*it).begin();
while ( it2 != (*it).end()) {
printf( "%d", *it2);
++it2;
}
printf( "n");
++it;
}
}
/**
*
* @param matrix
* Largest product in row using rolling multiplication
* @param n number of factors
* @param v factors of largest product
* @return largest product
*/
int largestProductInRow( Matrix& matrix, int n, vector< int>& v) {
if ( n > matrix.size()) return -1;
int res = 0;
int N = matrix.size() - n + 1; // number of products in row (or column)
/* search in rows */
outIt it = matrix.begin();
while (it != matrix.end()) {
inIt it2 = (*it).begin();
int currN = N;
int product = 1;
while (currN) { // rolling product calculation
inIt it3 = it2;
int currn = n;
if (currN == N) { // compute full product first time
while (currn) {
product *= (*it3++);
--currn;
}
} else { // rolling computation
product *= (*(it3 + n - 1)) / (*(it3 - 1));
it3 += n;
}
if (product > res) {
res = product;
copy(it3 - n, it3, v.begin());
}
--currN;
++it2;
}
++it;
}
return res;
}
用法:
/*
*
*/
int main(int argc, char** argv) {
Matrix matrix( 4, vector< int>());
fillMatrix( matrix);
printMatrix( matrix);
vector< int> v(3);
int res = largestProductInRow( matrix, 3, v);
printf( "res:%dn", res);
copy( v.begin(), v.end(), ostream_iterator<int>(cout, ","));
return 0;
}
结果:
res:42
7,2,3,
运行成功(总时间:113ms)
,假设我们有s x t矩阵(s列和t行)。
int res = 0;
if(s >= n)
{
for (int r = 0; r < t; ++r) // for each row
{
for (int i = 0; i <= s-n; ++i) //moving through the row
{
int mul = m[i][0];
for (int j = 1; j < n; ++j) //calculating product in a row
{
mul*=m[i][j];
}
if(mul > res)
{
res = mul;
//save i, j here if needed
}
}
}
}
if(t >= n)
{
for (int c = 0; c < s; ++c) // for each column
{
for (int i = 0; i <= t-n; ++i) //moving through the column
{
int mul = m[0][i];
for (int j = 1; j < n; ++j) //calculating product in a column
{
mul*=m[j][i];
}
if(mul > res)
{
res = mul;
//save i, j here if needed
}
}
}
}
如果您坚持蛮力,那么如您所说,您需要在所有[x,y]
上迭代,这将是行的起点。通过这些,您可以在各个方向上迭代k
相邻元素。您可以将说明作为向量存储在数组中。这将在O(k n^2)
中运行。
对于n x n
矩阵,并在行中寻找k
元素,类似C的伪代码看起来像这样(请注意,为简单起见,没有界限检查):
// define an array of directions as [x,y] unit vectors
// you only need to check in 4 directions, other 4 are the same, just reversed
int[4][2] dirs = {{1,0}, {1,1}, {0,1}, {-1,1}};
// iterate over all starting positions
for (x = 0; x < n; ++x) {
for (y = 0; y < n; ++y) {
// iterate over all directions
for (d = 0; d < 4; ++d) {
result = 1;
// iterate over elements in row starting at [x,y]
// going in direction dirs[d]
for (i = 0; i < k; ++i) {
// multiply current result by the element,
// which is i places far from the beginning [x,y]
// in the direction pointed by dirs[d]
new_x = x + i * dirs[d][0];
new_y = y + i * dirs[d][1];
// you need to check the bounds, i'm not writing it here
// if new_x or new_y are outside of the matrix
// then continue with next direction
result *= matrix[new_x][new_y];
}
if (result > max) {
max = result;
}
}
}
}
稍微好一点,少于蛮力的方式是从矩阵的边界开始,选择一个方向,然后朝这个方向朝矩阵的另一侧,将最后一个k
数字的乘积保持在途中。
步行时,您将产品保留,将其乘以您所需要的数字,然后除以在k
步骤前的数字。这样,当然有一些范围检查,该产品始终是最后一个k
数字的产品,因此,如果当前产品大于最大,只需让max = product
。这总是在O(n^2)
中运行。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 检查输入是否不是整数或数字
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何用数字处理log(0)
- 最高有效数字侧的第N位
- 如何获取一个数字的前3位
- 查找最接近的大于当前数字的数字的索引
- 找到两对数字,使它们的乘积的绝对差最小化
- 我想做一个彼此不同但重复出现的数字
- 将数字转换为字母(例如:123 转换为一二三)
- C++如何计算用户输入的数字中的偶数位数
- 如何在C++中确定文本文件中的元素是字符还是数字
- 打印数字图案
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 如何检查一个c++字符串中有多少相同的字符/数字
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 将数字打印成文字
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 在将数字随机生成为数组期间从内存输出随机数的数组