我试图平均列表中的负数并平均列表中的正数以及整个列表的平均值。这就是我到目前为止我所知道的并不多,但我不确定我的下一步应该是什么......
//这将读入n个值的列表,其中n未提前知道。读入数组的值的数量将保存在n。
中vector<int> readList()
{
std::vector<int> result;
ifstream inFile;
inFile.open("setA.txt");
for (int x; inFile >> x; )
{
result.push_back(x);
}
return result;
}
// array是一维整数数组,n是该数组中包含有效数据值的元素数。这两个都是函数的输入参数。该函数必须计算1)数组中n个整数的平均值,将结果存储在ave中; 2)正数的平均值(> 0),将结果存储在avePos中,以及3)负数的平均值(&lt; 0),将结果存储在aveNeg中。
void avgs (std::vector<int> &array, int &ave, int &avePos, int &aveNeg)
{
int sum = 0, pos_sum = 0, neg_sum = 0, pos_count = 0, neg_count = 0;
for (auto i : array)
{
sum += i;
if (i > 0) { pos_sum += i; ++pos_count; }
if (i < 0) { neg_sum += i; ++neg_count; }
}
if(pos_sum) avePos = pos_sum / pos_count;
if(neg_sum) aveNeg = neg_sum / neg_count;
}
答案 0 :(得分:3)
您可以使用自定义求和函数对accumulate
进行3次单独调用。或者你可以使用一个非常难看的求和函数来调用accumulate
。但是,为了便于阅读和提高效率,一个简单的for循环同时完成所有这三个循环会更好。
int sum = 0, pos_sum = 0, neg_sum = 0, pos_count = 0, neg_count = 0;
for (auto i : array)
{
sum += i;
if (i > 0) { pos_sum += i; ++pos_count; }
if (i < 0) { neg_sum += i; ++neg_count; }
}
确保在分割前检查pos_count
和neg_count
上的零。
答案 1 :(得分:1)
ave = sum/array.size();
那将进行整数除法。平均值很可能是浮点值,因此您需要先进行投射:
float ave = static_cast<float>(sum) / array.size();
要做其他平均值,你只需要分别总结正值和负值,然后分别除以正数和负数。
只是为了表明它可以做到:
void averages(const std::vector<int>& vec, double& overall_average, double& positive_average, double& negative_average)
{
std::tuple<int, int, int, int, int, int> sums_and_counts = std::accumulate(vec.begin(), vec.end(), std::make_tuple(0, 0, 0, 0, 0, 0), [](std::tuple<int, int, int, int, int, int> t, int i)
{
std::get<0>(t) += i;
std::get<1>(t) += 1;
if (i < 0)
{
std::get<2>(t) += i;
std::get<3>(t) += 1;
}
if (i > 0)
{
std::get<4>(t) += i;
std::get<5>(t) += 1;
}
return t;
});
overall_average = positive_average = negative_average = 0.0;
if (std::get<1>(sums_and_counts))
{
overall_average = static_cast<double>(std::get<0>(sums_and_counts)) / std::get<1>(sums_and_counts);
}
if (std::get<3>(sums_and_counts))
{
negative_average = static_cast<double>(std::get<2>(sums_and_counts)) / std::get<3>(sums_and_counts);
}
if (std::get<5>(sums_and_counts))
{
positive_average = static_cast<double>(std::get<4>(sums_and_counts)) / std::get<5>(sums_and_counts);
}
}
答案 2 :(得分:0)
我太懒了测试它,但我认为这样可行:
float avePos = static_cast<float>(accumulate(array.begin(), array.end(),
[](int sum, int x]->int
{
return sum + max(x, 0);
}) / static_cast<float>(array.size());
float aveNeg = static_cast<float>(accumulate(array.begin(), array.end(),
[](int sum, int x]->int
{
return sum + min(x, 0);
}) / static_cast<float>(array.size());
答案 3 :(得分:0)
更改accumulate
以仅添加负值:
int sum_neg = accumulate(array.begin(), array.end(), 0, [](int x, int y)
{
return x + ((y < 0)? y : 0);
});
答案 4 :(得分:0)
首先,您应该计算数组中有多少正面和负面元素。
您可以使用相同的std :: accumulate算法。例如
std::pair<int, int> count = std::accumulate( array.begin(), array.end(), std::make_pair( 0, 0 ),
[]( std::pair<int, int> p, int x )
{
return ( p.first += x < 0, p.second += x > 0, p );
} );
然后你可以使用基于范围的for语句来获得相应的总和:
ave = aveNeg = avePos = 0;
for ( int x : array )
{
ave += x;
if ( x < 0 ) aveNeg += x;
if ( 0 < x ) avePos += x;
}
if ( !array.empty() ) ave /= ( int )array.size();
if ( count.first ) aveNeg /= count.first;
if ( count.second ) avePos /= count.second;
答案 5 :(得分:0)
我认为本杰明林德利给出的答案是可以的,但要小心使用整数变量的int类型。根据您的输入值,它可能很容易溢出。如果使用32位int,或者使用double,可能使用64位整数。这一切都取决于预期的输入值范围。