Suche Funktion/Algorithmus zum Zusammenfassen von Containern



  • Hallo zusammen,

    Ich suche eine Funktion/einen Algorithmus, mitdem ich zwei (oder mehr) Container zusammenfassen kann:
    Es wird ein Container c erzeugt indem abwechselnd ein Element von Container a und ein Element von Container b eingefügt wird.
    Die Reihenfolge im Container c ist am Ende:

    a1, b1, a2, b2, ...
    

    Schön wäre auch, wenn man das auch mit drei/vier/... Containern machen könnte.
    Gibt es so eine Funktion/einen Algorithmus?
    Schon mal danke,
    Nathan



  • In der STL gibt es sowas nicht, aber der ist ja flott selbst geschrieben. Versuchs einfach mal. Tip: Wenn du nicht direkt ganze Container sondern Input-Iteratoren übergibst, könnte es besonders wiederverwendbar werden.



  • template <class InputIterator1, class InputIterator2,
              class OutputIterator>
      OutputIterator merge_alternately ( InputIterator1 first1, InputIterator1 last1,
                                         InputIterator2 first2, InputIterator2 last2,
                                         OutputIterator result)
     {
            size_t ct(0);
            while(first1 != last1
              and first2 != last2)
                    *result++ = (++ct % 2 ? *first1++ : *first2++);
    
            std::copy(first1, last1, result);
            std::copy(first2, last2, result);
    
            return result;
     }
    

    Mal schnell gebastelt. Falls die Mengen nicht gleich groß sind, werden überschüssige Elemente angehängt, also muss im Output immer genug Platz für beide Mengen zusammen sein.
    Die Elemente des ersten Iteratorenpaars werden zuerst genommen (also ABAB und nicht BABA).

    Edit:
    ➡ Hier der Ideone Test.



  • Hab auch einen netten Algorithmus gefunden:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void swap(vector<int>& v, int i, int j)
    {
    	int t = v[i];
    	v[i]  = v[j];
    	v[j]  = t;
    }
    
    void in_place_algorithm(vector<int>& v)
    {
    	int n = v.size()/2;	
    	for ( int i = n-1; i > 0; i-- )
    		for ( int j = n-1; i+j>=n; j-- )
    			swap(v,j,i+j);
    } 
    
    int main()
    {
    	int ar[] = {1,3,5,7,9,2,4,6,8,0};
    	vector<int> v(ar,ar+10);
    
    	in_place_algorithm(v);
    
    	for(int i=0; i<v.size(); ++i)
    		cout << endl << v[i];
    }
    


  • NathanM schrieb:

    Schön wäre auch, wenn man das auch mit drei/vier/... Containern machen könnte.

    Ich glaube, das Problem ist nicht wirklich trivial. Mal gespannt, ob hier jemand etwas dafür liefert.



  • Wäre doch mit variadic Templates und den den Iteratoren-Paaren als pair verpackt gut lösbar. Halt wie Hackers Lösung.



  • Ethon schrieb:

    Halt wie Hackers Lösung.

    *Sone 🙂

    Ich habs btw gleich. Aber unschön 😞



  • Ja, so ging es mir auch.
    War unschön, klappt mit Ach und Krach.
    Also es gibt da nichts vordefiniertes, schade..


  • Mod

    #include <initializer_list>
    #include <iterator>
    #include <vector>
    #include <iostream>
    
    template <typename OutputIterator, typename Size, typename... InputIterator>
    OutputIterator zip_merge_n(OutputIterator out, Size n, InputIterator... in)
    {
        for ( ; n--; )
            (void)std::initializer_list<bool>{ ( ( *out++ = *in++ ), false )... };
        return out;
    }
    
    int main()
    {
        std::vector<int> a = { 1, 5, 10 }, b = { 23, 42, 87 };
        zip_merge_n( std::ostream_iterator<int>( std::cout, "\t"), a.size(), begin( a ), begin( b ) );
        std::cout << '\n';
    }
    


  • Coole for-Schleife 😃

    Ansonsten wohl die hammermäßigste Lösung, die man sich vorstellen kann.



  • Sone, was ist mit deinem gleich passiert. 😃



  • out schrieb:

    Sone, was ist mit deinem gleich passiert. 😃

    Meins kannste in die Tonne kicken ... 😃



  • @camper:
    He, danke.
    Ist genau das, was ich gesucht habe.


Anmelden zum Antworten