العثور على عناصر المصفوفة على أساس الحد الأدنى مبلغ

StackOverflow https://stackoverflow.com/questions/853007

  •  21-08-2019
  •  | 
  •  

سؤال

ولقد كتبت حلقة في C ++ أن تعطيني 6 أرقام عشوائية وتخزينها في صفيف.  ما أود القيام به هو تلخيص عناصر المصفوفة حتى أحصل على قيمة أكبر من عدد "س"، ولكن أود أن تفعل ذلك دون إضافة بالضرورة جميع العناصر. الهدف هو العثور على أول العناصر التي المبلغ إلى قيمة x.

وعلى سبيل المثال، مجموعة هي [1,2,3,4,5,6]، وx = 6، وذلك ما أرجو أن تبحث عن هي [1,2,3] العناصر.

ولقد بحثت في المكتبة القياسية ولقد حاولت استخدام وظيفة المبلغ من "valarray" ولكن هذا يعطي مجرد حاصل جمع كل العناصر. ومن شأن أي الأفكار حول كيفية رمز هذا بنجاح سيتم تقدير كبير.

هل كانت مفيدة؟

المحلول

وكتابة functor أن يفعل الإضافة.

#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));
 }

نصائح أخرى

وأفترض أنك تريد فقط العناصر X الأولى في مجموعة، حتى يلتقي مجموعهما أو يتجاوز عتبة (كان السؤال قليلا غامضة هناك).

وإذا كان الأمر كذلك، وأنا لا أعرف كيف نفعل ذلك دون حلقة الخاصة بك:

int sum = 0;
int i = 0;
for( ; i < len; ++i ) {
    sum += array[i];
    if( sum >= 6 ) {
        break;
    }
}

والآن "أنا" يحتوي على مؤشر الذي التقى المبلغ أو تجاوز عتبة الخاص بك.

وتجنب الإجابات التي أقترح استخدام find_if مع المسند جليل. المسندات جليل خطيرة كما تفترض خوارزميات STL أنها آمنة لنسخ المسندات. في هذه الحالة، إذا تم إجراء نسخ أصلية ثم سوف يكون كل مختلفة "مجموعه تشغيل" ولن تعمل بالضرورة على جميع القيم، أو في الترتيب الصحيح.

وخصوصا تجنب الحل الذي ينفذ عضوا أصليا لها في المشغل () كدالة عضو CONST لكن التسميات أعضائها قابلة للتغيير لأن هذا هو خداع كنت أفكر في أنها ليست أصلية جليل، وهو أمر سيء.

وأنا أقترح باستخدام واحدة من الإجابات التي حلقات مجرد العثور على الجواب، أو الإجابة يستخدم اللاسلكي، لأن ذلك هو السبيل الأكثر الصحيحة للقيام بذلك (حتى إذا كان رمز يبدو غير عملي قليلا.

لاحظ أنه قد لا تنطبق جيدا التحذيرات صفائف C وfind_if. أنا فقط لا أريد لك أن تعلم أن يسند جليل هي الطريق الصحيح لحل مشكلتك وبما انك قد ينتهي باستخدام هذا الحل غير صحيح في الحالة التي تكون فيها أنه أمر خطير في المستقبل.

والمرجعي: C ++ الترميز المعايير: 101 القواعد، المبادئ التوجيهية، وأفضل الممارسات، البند 87

وهنا نسخة قليلا أكثر عمومية:

#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;
}

وطرح الأرقام من س احدا تلو الآخر، حتى تصل إلى 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;
}

وسيكون شيئا مثل:

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));

حسنا، وأود أن استخدام ناقلات

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 سيحتاج المشغل والمشغل + <تحدد بعد.

هل يمكن استخدام الأمراض المنقولة جنسيا :: find_if () جنبا إلى جنب مع functor التي تحافظ على ما مجموعه التوالي، وفقط صحيح returtn من functor عندما كنت قد وجدت العنصر الذي يضعك في أو فوق.

وعلى سبيل المثال:

#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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top