بالتكرار عبر عناصر الزوج في وعاء يحتوي على أزواج (C ++)

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

سؤال

وإذا كان لدي الحاويات (vector، list، الخ) حيث أن كل عنصر هو std::pair، هناك طريقة سهلة لتكرار عبر كل عنصر من كل زوج؟

وأي بمعنى.

std::vector<std::pair<int,int> > a;
a.push_back(std::pair(1,3));
a.push_back(std::pair(2,3));
a.push_back(std::pair(4,2));
a.push_back(std::pair(5,2));
a.push_back(std::pair(1,5));

ومن ثم التمكن من تكرار على القيمة: 1،3،2،3،4،2،5،2،1،5

وعلى نحو مماثل، ما هو نوع من functor / وظيفة سيعود لي وعاء (من نفس النوع) مع قائمة مسطحة من العناصر الزوج على النحو الوارد أعلاه؟

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

المحلول

لتتسطح الحاويات من أزواج في وعاء الثانية يمكن أيضا ببساطة كتابة الواضع الخاص بك:

template<class C>
struct Inserter {
    std::back_insert_iterator<C> in;
    Inserter(C& c) : in(c) {}
    void operator()(const std::pair<typename C::value_type, typename C::value_type>& p)
    {
        *in++ = p.first;
    *in++ = p.second;
    }
};

template<class C>
Inserter<C> make_inserter(C& c)
{ 
    return Inserter<C>(c); 
}

// usage example:
std::list<int> l;
std::for_each(a.begin(), a.end(), make_inserter(l));

نصائح أخرى

لديك أولا، عليك أن خلق لكم من الدرجة مكرر الخاصة، التي أزواج إشارة تشير إلى الموقف داخل الزوج مع مكرر container<pair>

لثاني، فإنه من السهل، على الرغم من أن عامة ما تريد (حاوية من نفس النوع) كنت في حاجة الى <وأ href = "http://www.gotw.ca/gotw/079.htm" يختلط = "noreferrer"> قالب typedef و. وهنا لمجرد ناقل:

template <class V>
std::vector<V> flatten_pairs(std::vector<std::pair<V,V> > const& a) {
  typedef std::vector<std::pair<V,V> > A;
  std::vector<V> ret;
  for (typename A::const_iterator i=a.begin(),e=a.end();i!=e;++i) {
    ret.push_back(i->first);
    ret.push_back(i->second);
  }
  return ret;
}

وهنا هو كيف همية typedef والقالب:

template <class C>
struct same_container;

template <class V>
struct same_container<std::vector<V> > {
  template <class W> struct rebind { typedef std::vector<W> type; };
};

template <class V>
struct same_list<std::list<V> > {
  template <class W> struct rebind { typedef std::list<W> type; };
};

template <class C>
typename same_container<C>::rebind<typename C::value_type::first_type>::type
flatten_pairs(C const& a);

والتعليمة البرمجية التالية ستطبع كل القيم كما هو مطلوب:

for ( size_t x = 0; x < a.size(); ++x ) {
    cout << a[x].first << "," << a[x].second << ",";
}

وكنت تفضل هذه الطريقة سهلة من إنشاء مكرر المخصصة.

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

لا، هناك حقا لا شيء من هذا القبيل لstd::pair. قد ترغب في النظر في استخدام الصفوف (tuple) دفعة بدلا من ذلك. A الصفوف (tuple) قليلا مثل نسخة موسعة من std::pair التي تسمح عدد التعسفي من العناصر (إلى بعض الحد، ولكن عادة ما لا يقل عن 10)، ويتيح الوصول إلى العناصر شيء مثل ناقلات / مجموعة، وكذلك (أي يمكنك الوصول العناصر إما عن طريق الاسم أو رقم قياسي).

ويشمل TR1 أيضا الأمراض المنقولة جنسيا :: :: TR1 الصفوف (tuple)، وهي مجموعة فرعية من الصفوف (tuple) دفعة، ولكن إذا أسعفتني الذاكرة، فإنه لا يزال يتضمن وظيفة اسم / مؤشر كنت طالبا.

وتحرير: لاحظ أنه في كلتا الحالتين، يتطلب تدوين المؤشر <م> تجميع الوقت ثابت للمؤشر، لذلك لا يمكن أن يكتب حلقة (وقت التشغيل) لتكرار عبر العناصر في والصفوف (tuple) - ولكن يمكنك القيام بهذه المهمة مع قليل من metaprogramming. ويشمل دفعة الانصهار لا بأس به لدعم ما كنت بحاجة (من قبل بعض صدفة غريبة، الصفوف (tuple) هي جزء من مكتبة الانصهار).

وعند نقطة معينة تحتاج إلى استخدام <م> أولا و <م> الثانية ، حتى لو كنت إنشاء فئة مكرر الخاصة بك. أنا لا أعتقد أن هناك وسيلة للخروج منه (على الأقل، بطريقة المحمولة).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top