我需要找到两个具有最大乘积的数组元素,然后输出它们的乘法。我试图对数组进行排序,然后搜索最大乘积,但是我的代码无法用于多个输入(我将在问题末尾给出),因为结果是0.00。我想我的if语句找不到要分配给'sand'的正确值,但是我不知道该如何写。 这是我正在使用的代码:
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <functional>
using namespace std;
int main() {
int n;
double a[10], sand=0;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a,a+n);
for(int i = 0; i <n; i++)
{ for (int j=i+1;j<n;j++){
if(a[i]*a[j]>i*j)
{ sand=(a[i])*(a[j]);
}
}
}
cout<<fixed<<setprecision(2)<<sand;
}
这是输入:
2
5 -8
这是我应该得到的输出:
-40.00
我得到0.00
代替。
第二个输入:
4
0 0.2 0.4 0.5
我应该得到的输出:
0.20
我的代码再次获得0.00
作为输出。
答案 0 :(得分:2)
对数组排序一次(假设n >= 2
),结果是:
std::max(a[0] * a[1], a[n - 2] * a[n - 1]);
a[0] * a[1]
处理“大”负数。
a[n - 2] * a[n - 1]
处理一般情况:“大”正数。
您的第二个循环看起来像蛮力的,因此应该(不再需要std::sort
):
auto sand = a[0] * a[1];
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
srand = std::max(srand, a[i] * a[j]);
}
}
答案 1 :(得分:2)
您可以在O(n^2)
的时间内找到答案,而不是使用两个for循环(复杂度O(nlog(n))
)或使用排序(复杂度O(n)
。而且,您甚至不需要数组来存储数字!
跟踪两个最低元素和两个最高元素。令变量为minA
,minB
,maxA
,maxB
。数组中任何两个数字的最大乘积将为minA*minB
或maxA*maxB
。
假设n >= 2
,
#include <iostream>
#include <limits>
#include <algorithm>
using namespace std;
constexpr double MIN = numeric_limits<double>::min();
constexpr double MAX = numeric_limits<double>::max();
int main()
{
int n;
cin >> n;
double minA, minB, maxA, maxB;
minA = minB = MAX;
maxA = maxB = MIN;
for (int i = 0; i < n; ++i)
{
double x;
cin >> x;
if (x > maxA)
{
maxB = maxA;
maxA = x;
}
else if (x > maxB)
maxB = x;
if (x < minA)
{
minB = minA;
minA = x;
}
else if (x < minB)
minB = x;
}
cout << max(minA * minB, maxA * maxB) << endl;
}
答案 2 :(得分:1)
您可以使用四种潜在的算法,如下所示:
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <vector>
//O(N^2): Compare all elements against each other and keep the biggest product
//We pass `data` by value so the order of the array as invariant between tests
template<class T>
T Method1(std::vector<T> &data){
assert(data.size()>=2);
T bestval=data[0]*data[1];
for(int i=0;i<data.size();i++)
for(int j=i+1;j<data.size();j++){
const auto val = data[i]*data[j];
if(val>bestval)
bestval = val;
}
return bestval;
}
//O(N log N): Sort the elements and look at the largest potential products
//We pass `data` by value so the order of the array as invariant between tests
template<class T>
T Method2(std::vector<T> &data){
assert(data.size()>=2);
std::sort(data.begin(), data.end());
return std::max(data[0]*data[1], data[data.size()-1]*data[data.size()-2]);
}
//O(N): Use Quickselect to look at the largest potential products
//We pass `data` by value so the order of the array as invariant between tests
template<class T>
T Method3(std::vector<T> &data){
assert(data.size()>=2);
std::nth_element(data.begin(),data.begin()+1,data.end());
auto smallval = data[0]*data[1];
std::nth_element(data.begin(),data.end()-2,data.end());
auto bigval = (data[data.size()-2]*data[data.size()-1]);
return std::max(smallval,bigval);
}
//O(N): Explicitly find the pairs with the largest potential products
//We pass `data` by value so the order of the array as invariant between tests
template<class T>
T Method4(std::vector<T> &data){
assert(data.size()>=2);
T small1 = std::numeric_limits<T>::max();
T small2 = std::numeric_limits<T>::max();
T large1 = std::numeric_limits<T>::min();
T large2 = std::numeric_limits<T>::min();
for(const auto &x: data){
if(x<=small1){
small2 = small1;
small1 = x;
} else if(x<=small2){
small2 = x;
}
if(x>=large1){
large2 = large1;
large1 = x;
} else if(x>=large2){
large2 = x;
}
}
return std::max(small1*small2,large1*large2);
}
template<class Func>
void TimeIt(std::string message, Func func){
long x; //Dummy variable to prevent compiler optimizations
const auto start = std::chrono::high_resolution_clock::now();
const int TEST_COUNT=100;
for(int i=0;i<TEST_COUNT;i++)
x += func();
const auto finish = std::chrono::high_resolution_clock::now();
std::cout << message <<" time: " << std::fixed << ((std::chrono::duration<double>)(finish-start)).count()/TEST_COUNT << "s "<<std::endl;
}
int main(){
const int N=100000;
std::vector<long> data; //Don't change this
std::vector<long> data_orig; //Let the methods mutate this
data.reserve(N);
for(int i=0;i<N;i++){
data.push_back(rand()%2000001-1000000); //Get a random number in the range [-1000000,1000000]
}
data_orig = data;
std::cout<<"Method1 = "<<Method1(data)<<std::endl;
std::cout<<"Method2 = "<<Method2(data)<<std::endl;
std::cout<<"Method3 = "<<Method3(data)<<std::endl;
std::cout<<"Method4 = "<<Method4(data)<<std::endl;
//Do they all give the same answer?
assert(Method1(data)==Method2(data));
assert(Method2(data)==Method3(data));
assert(Method3(data)==Method4(data));
TimeIt("Method1", [&](){data=data_orig; return Method1(data);});
TimeIt("Method2", [&](){data=data_orig; return Method2(data);});
TimeIt("Method3", [&](){data=data_orig; return Method3(data);});
TimeIt("Method4", [&](){data=data_orig; return Method4(data);});
}
在我的计算机上,所有这些都给出了相同的答案,这很好地证明了它们是正确的:
Method1 = 999976000143
Method2 = 999976000143
Method3 = 999976000143
Method4 = 999976000143
计时结果符合我们的预期,平均得到了100次迭代:
Method1 time: 2.624980s
Method2 time: 0.004581s
Method3 time: 0.000806s
Method4 time: 0.000118s