我在C ++中编写了一个循环,给我6个随机数并将它们存储在一个数组中。 我想要做的是总结数组的元素,直到我得到一个大于数字“x”的值,但我想这样做而不必添加所有元素。目标是找到第一个与x的值相加的元素。
例如,数组是[1,2,3,4,5,6]
和x = 6
,所以我要找的是元素[1,2,3]
。
我查看了标准库,并尝试使用“valarray”中的sum函数,但这只是给出了所有元素的总和。任何关于如何成功编码的想法都将不胜感激。
答案 0 :(得分:11)
编写一个执行添加的函子。
#include <algorithm>
struct SumToo
{
SumToo(int val):m_val(val),m_sum(0) {}
int m_val;
int m_sum;
bool operator()(int next)
{
m_sum += next;
return m_sum >= m_val;
}
};
int main()
{
int data[] = {1,2,3,4,5,6};
int* find = std::find_if(data,data+6,SumToo(6));
}
答案 1 :(得分:7)
我假设你只想要数组中的前X个元素,直到它们的总和达到或超过阈值(那里的问题有点模糊)。
如果是这样,我不知道如何在没有你自己的循环的情况下做到这一点:
int sum = 0;
int i = 0;
for( ; i < len; ++i ) {
sum += array[i];
if( sum >= 6 ) {
break;
}
}
现在“i”包含总和达到或超过阈值的指数。
答案 2 :(得分:3)
避免使用带有状态谓词的find_if建议的答案。有状态谓词是危险的,因为STL算法假设复制谓词是安全的。在这种情况下,如果副本是由谓词构成的,则每个副本将具有不同的“运行总计”,并且不一定会对所有值或正确的顺序起作用。
特别是避免将谓词的operator()成员实现为const成员函数的解决方案,但将其成员标记为可变,因为这会让你误以为它不是有状态谓词,这很糟糕。
我建议使用其中一个简单循环来找到答案的答案,或者使用累加器的答案,因为这是最正确的方法(即使代码看起来有点笨拙。< / p>
请注意,警告可能不适用于C数组和find_if;我只是不希望您了解有状态谓词是解决问题的正确方法,因为您可能会在将来危险的情况下使用该错误解决方案。
参考:C ++编码标准:101规则,指南和最佳实践,第87项
答案 3 :(得分:2)
逐个减去 x 中的数字,直到达到0或更低。
没有任何补充,如你所愿:)
答案 4 :(得分:2)
这是一个稍微更通用的版本:
#include <iostream>
#include <algorithm>
// return an iterator _Last such that sum
// of all elements in the range [_First, _Last)
// satisfies the predicate Func
template<class InIt,
class Ty,
class Fn> inline
InIt accumulate_if(InIt First, InIt Last, Ty Val, Fn Func)
{
for (; Func(Val) && First != Last; ++First)
Val = Val + *First;
return (First);
}
int main() {
int num[] = {1, 2, 3, 4, 5, 6};
int *last = accumulate_if(num, num + sizeof num / sizeof num[ 0 ],
0, std::bind2nd(std::less<int>(), 6));
std::copy(num, last, std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
答案 5 :(得分:0)
好吧,我会使用矢量
T addUntil(T array[],size_t len,T thres){
vector<T> vec = vector_from_array(array,len)
T sum;
for (size_t i=0;i< vec.size(),sum<thresh;i++){
sum+= vec[i];
}
return sum;
}
T需要操作员和操作员&lt;待定义。
答案 6 :(得分:0)
会是这样的:
struct StopAtValue{
StopAtValue(int sum) : m_sum(sum), m_accumulated(0){}
bool operator()(int val){
m_accumulated += val;
return m_accumulated >= sum;
}
int m_sum;
int m_accumulated;
}
int* pos = std::find_if(&array[0], &array[n], StopAtValue(6));
答案 7 :(得分:0)
希望这有效:
/* Returns an index i, given array valarray[0,1..n] and number x where i is an index to valarry such that sum over j of valarray[j] for j = 0 to i > x */
int getFirstSum(int *valarray, int n, int x)
{
int i = 0;
int sum = x;
while(sum > x && i < n)
{
i++;
sum -= valarray[i];
}
return i;
}
答案 8 :(得分:-1)
你可以使用std :: find_if()和一个保持运行总数的仿函数,只有当你找到了将你置于顶部或顶部的元素时,才能从仿函数中返回true。
例如:
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
using namespace std;
// functor returns true when the running total >= findVal
struct running_total : public unary_function<int, bool>
{
running_total(int findVal) : findVal_(findVal), runningTtl_(0) {};
bool operator()(int rhs) const
{
runningTtl_ += rhs;
if( runningTtl_ >= findVal_ )
return true;
else
return false;
}
private:
mutable int runningTtl_;
const int findVal_;
};
int main()
{
int nums[] = {1, 2, 3, 4, 5, 6};
size_t count = sizeof(nums)/sizeof(nums[0]);
const int scanTtl = 6; // running total to scan to
int * pos = find_if(&nums[0], &nums[0]+count, running_total(scanTtl));
cout << "Elements Totaling " << scanTtl << " : ";
copy(&nums[0], pos+1, ostream_iterator<int>(cout, ", "));
return 0;
}