我需要计算实际索引左侧和右侧数组中的最大数字。我的意思是如果我的数组是
1, 3, 2, 4, 3;
我需要输出:
//Left Right
1 4 //no bigger on left, so 1; the biggest on right is 4
3 4 //and so on with rest points
3 4
4 4
4 3
我需要非常快速地做到这一点,所以只是在左边然后在右边兜售是一个坏主意。我决定在右边找到最大的,然后当我到达那里时计算下一个,依此类推。左边最大,只要实际大于它,改变它。但它不起作用......程序有时会输出错误的结果。不幸的是,我不知道它做了什么输入...
这是我的代码,如果您可以看到任何一般或算法错误我很高兴如果您可以发布它...
#include <cstdlib>
#include <iostream>
using namespace std;
inline int findmax(int tab[], int beg, int end)
{
int max=0;
for (int j=beg; j<end; j++)
if (tab[j]>max) max=j;
return max;
}
int main(int argc, char *argv[])
{
int len;
cin>>len;
int h[len];
for (int i=0; i<len; i++)
cin>>h[i];
int maxl=0, maxr;
maxr=findmax(h,0,len);
for (int i=0; i<len; i++)
{
if (h[i]>h[maxl]) maxl=i;
if (i>maxr) maxr=findmax(h,i,len);
cout<<h[maxl]<<" "<<h[maxr]<<endl;
}
//system("pause");
return 0;
}
编辑: 我已阅读所有回复并予以实施。一个问题是我不能将值存储在第一个循环中,所以我必须&#34;合并&#34;这两个是......这是我现在的代码:
#include <cstdlib>
#include <iostream>
using namespace std;
inline int findmax(int tab[], int beg, int end)
{
int max=0;
for (int j=beg; j<end; j++)
if (tab[j]>max) max=j;
return max;
}
int main(int argc, char *argv[])
{
int len;
cin>>len;
int h[len];
int l[len];
for (int i=0; i<len; i++)
cin>>h[i];
int maxl=0, maxr;
maxr=len-1;
for (int i=len-1; i>=0; i--)
{
if (h[i]>h[maxr]) maxr=i;
l[i]=h[maxr];
}
for (int i=0; i<len; i++)
{
if (h[i]>h[maxl]) maxl=i;
cout<<h[maxl]<<" "<<l[i]<<endl;
}
//system("pause");
return 0;
}
答案 0 :(得分:6)
由于嵌套循环,您的程序的时间复杂度为O(n ^ 2)。但这可以在线性时间内完成:
您已经知道如何找到每个元素左侧的最大元素:迭代所有元素,跟踪当前最大值。每个元素左边最大的元素是当你到达那个元素时的当前最大值。
要找到每个元素右边的最大元素,你可以反过来做同样的事情:从右到左迭代数组,跟踪当前的最大值。
所以你有两个循环(从左到右和从右到左),但它们不会相互嵌套,因此对于大型数组来说性能要好得多。
答案 1 :(得分:2)
使用std::max_element和std::count。或者使用std::for_each自定义类来自行查找索引。
inline int findmax(int tab[], int beg, int end)
{
int max=0;
for (int j=beg; j<end; j++)
if (tab[j]>max) max=j;
return max;
}
如果数组中的所有元素都为负数,则无效。使用std::numeric_limits<int>::min()
作为初始值。
答案 2 :(得分:2)
要回答你的程序无法正常工作的问题:findmax()返回一个存储在maxr中的值,但是你使用maxr作为索引,所以你应该有一个函数返回最大值的索引而不是价值。
编辑(如barnes53指出):实际上,在findmax()函数中,max用作索引和值。至少&#34; if(tab [j]&gt; max)max = j;&#34;必须是&#34; if(tab [j]&gt; tab [max])max = j;&#34;。如果该函数被称为findIndexOfMax()。它将帮助我。
答案 3 :(得分:2)
对已接受答案的改进:
你可以通过中途消除至少25%(可能是50%)的比较。
从左侧开始,随时计算“左侧最大值”。从右边开始,随时计算“正确的最大值”。
在中间会议后,在会合点比较左边的最大值和右边的最大值。如果它们相等,那么你知道其余计算的答案(你已经节省了50%的计算)。如果它们不相等,那么你必须在两半中具有更大最大值的那一侧继续计算,直到那个那边达到最大值,然后你知道那边的其他人的答案。
答案 4 :(得分:1)
stefaanv(大约)确定了你的问题,所以我只展示一个不是O(n ^ 2)的实现。
编辑:最小内存使用
#include <iostream>
#include <array>
#include <algorithm>
int main()
{
std::array<int,5> input = {1, 3, 2, 4, 3}; // max_right
std::array<int,5> max_left;
max_left[0] = input[0];
for(int i=1;i<input.size();++i) {
max_left[i] = std::max(max_left[i-1],input[i]);
}
for(int i=input.size()-2;i>=0;--i) {
input[i] = std::max(input[i+1],input[i]);
}
for(int i=0;i<input.size();++i) {
std::cout << max_left[i] << ' ' << input[i] << '\n';
}
}
答案 5 :(得分:1)
这是interjay正在谈论的实现:
#include <iostream>
#include <limits.h>
#define LENGTH 5
int h[LENGTH] = {1, 3, 2, 4, 3};
int maxl[LENGTH], maxr[LENGTH];
int main(int argc, char **argv)
{
int max = INT_MIN;
for(int i = 0; i < LENGTH; i++)
{
if (h[i] > max){ max = h[i]; }
maxl[i] = max;
}
# Left to right, computer maxl
max = INT_MIN;
for(int i = LENGTH-1; i >= 0; i--)
{
if (h[i] > max){ max = h[i]; }
maxr[i] = max;
}
# Right to left, computing maxr
for (int i = 0; i < LENGTH; i++)
{
std::cout << maxl[i] << " " << maxr[i] << std::endl;
}
return 0;
}
听起来你的记忆力有限。在这种情况下,如果只将第一个和第三个循环组合在一起,则可以删除maxl
数组,在计算它们时打印最大值。如果不明白该怎么做,请告诉我。