Miniprog: Wer liefert schnellstes snippet :) -> anzahl gleicher zahlen in folge



  • int a[] = { 1,1,2,2,2,3,3,5,5,5,5,5 };
    const int num = sizeof(a)/sizeof(int);
    
    map<int,int> mappo;
    
    for(int i=0; i<num; ++i)
            ++mappo[a[i]];
    

    @Simon: Ich nehms dir net übel 🙂

    Simon2 schrieb:

    Hab gerade keinen Compiler

    ~Anstatt nen neuen Beitrag zu schreiben, editiere ich meine alten 🙄~



  • KasF schrieb:

    ...

    @Simon: Ich nehms dir net übel 🙂

    Simon2 schrieb:

    Hab gerade keinen Compiler

    Ja, hast ja Recht ... meine ursprünglich feste "10" wäre wohl besser gewesen - außerdem ist Deins ja nun wirklich kürzer und eleganter ! Super !

    Gruß,

    Simon2.



  • Mit Hilfe des Compilers nochmal verbessert:

    struct counter_copy {
       counter_copy(int* s, int* e, size_t* p) : start(s), end(e), pos(p) {}
       int *start, *end;
       size_t *pos;
       void operator()(int val) { *pos = count(start, end, val); ++pos; }
    };
    

    Die Methode von mir hatte ich mal von hier aufgeschnappt: http://www.cppreference.com/cppmap/all.html , nur bissl unsauber, da meine Indizes die Zahlen aus dem Array sind und somit jede Menge Stellen in der map leer sind, also 0 ausgegeben werde würde, wenn man durchiteriert. Aber die könnte man ja alle einfach noch entfernen, weiß aber im moment nicht wie ...


  • Mod

    KasF schrieb:

    Die Methode von mir hatte ich mal von hier aufgeschnappt: http://www.cppreference.com/cppmap/all.html , nur bissl unsauber, da meine Indizes die Zahlen aus dem Array sind und somit jede Menge Stellen in der map leer sind, also 0 ausgegeben werde würde, wenn man durchiteriert. Aber die könnte man ja alle einfach noch entfernen, weiß aber im moment nicht wie ...

    Es soll ja ein Ergebnisarray werden, dann können wir kopieren und die Nullen gleichzeitig entfernen:

    std::vector<int> ergebnis;
    remove_copy(mappo.begin(),mappo.end(),back_inserter(ergebnis),0);
    


  • camper schrieb:

    std::vector<int> ergebnis;
    remove_copy(mappo.begin(),mappo.end(),back_inserter(ergebnis),0);
    

    Mit remove etc. bin ich mich ja die ganze Zeit am rumschlagen. Wenn remove den Iterator dereferenziert kommt ja ein pair<> dabei raus und der kann nicht einfach mit 0 verglichen werden. Man könnte das mit Funktionsobjekten etc. ausbauen, damit es funkitoniert, aber wäre keine EinZeilenLösung, so wie es sonst funktioniert: ( Kann sein das ich mich mit dem geschriebenen irren könnte ).

    Komischerweise werden die 0'en nur bei normalen indiziertem iterieren angezeigt nicht wenn ich über Iteratoren gehe:

    for(map<int,int>::iterator it = mappo.begin(); it != mappo.end(); ++it)
        cout << it->second;
    //2325
    
    for(int i=0; i<mappo.size(); ++i)
            cout <<mappo[i];
    //023205
    

    Ein neues Phänomen für mich 🙂


  • Mod

    KasF schrieb:

    Wenn remove den Iterator dereferenziert kommt ja ein pair<> dabei raus und der kann nicht einfach mit 0 verglichen werden.

    Stimmt - hab ich geschlafen.

    KasF schrieb:

    Komischerweise werden die 0'en nur bei normalen indiziertem iterieren angezeigt nicht wenn ich über Iteratoren gehe:

    Ein neues Phänomen für mich 🙂

    Weil mappo[0] erst in deiner Schleife angelegt wird 😉



  • KasF schrieb:

    nur bissl unsauber, da meine Indizes die Zahlen aus dem Array sind und somit jede Menge Stellen in der map leer sind, also 0 ausgegeben werde würde, wenn man durchiteriert.

    Äh, nein. Du musst einfach nur mit den Map-Iteratoren durchgehen, nicht mappo[index] .



  • camper schrieb:

    Weil mappo[0] erst in deiner Schleife angelegt wird 😉

    Ahhhhhhhhh 🙂 (oh man)

    Wieso funktioniert das denn nicht:

    pair<int,int> eraser(0,0);
    remove_copy(mappo.begin(),mappo.end(),back_inserter(ergebnis),eraser);
    

    Macht zwar keinen Sinn, da ja beide Paar-Objekte gleich sein müssen, aber trotzdem.

    stl_algo:remove_copy(...)
    if (!(*__first == __value))
    /*
    error: no match for 'operator==' in '(&__first)->std::_Rb_tree_iterator<_Tp>::operator* [with _Tp = std::pair<const int, int>]() == __value'
    */
    

    😕
    Liefert *__first kein pair<int,int> zurück ?

    Edit: Ja finix, der Groschen ist soeben gefallen.



  • camper schrieb:

    Es soll ja ein Ergebnisarray werden, dann können wir kopieren und die Nullen gleichzeitig entfernen:

    std::vector<int> ergebnis;
    remove_copy(mappo.begin(),mappo.end(),back_inserter(ergebnis),0);
    

    Wie wär's mit

    std::vector<int> result(result_size); // result_size laut Aufgabenstellung bekannt
    transform(mappo.begin(),
              mappo.end(),
              result.begin(), // edit: statt c&p-Fehler "back_inserter(result)",
              select2nd<map<int, int>::value_type>());
    

    Edit:

    KasF schrieb:

    Edit: Ja finix, der Groschen ist soeben gefallen.

    Hehe, ja ich seh's. Sollte mir echt angewöhnen meine Tabs hin und wieder zu refreshen 😞



  • Die Anzahl gleicher Zahlen (Thread Text) oder gleicher Zahlen in Folge (Thread Titel)?
    Die Anzahl gleicher Zahlen in Folge ist trivial und geht ungefähr so:

    void lala(int const* in, size_t size, int* out)
    {
        for (size_t i = 1; i < size; i++)
        {
            (*out)++;
            if (in[i] != in[i-1])
                out++;
        }
    }
    


  • @hustbaer: da stimmt noch was mim letzten index nicht....also bei der berechnung der letzten gleichen zahlen....ich schau gerade...



  • hustbaer hat halt vorher nicht sortiert 🤡



  • 😕 WAS?

    dann gehts doch erste recht nicht ...oder bin ich jetzt shcon ganz blind vor bäumen



  • achso.....er meint die anzahl gleicher zahlen in FOLGE....
    also sowas: 223322244 wäre 2232

    ich aber brauche halt: 522 weil 5 2er auftauchen 🙂



  • Das kürzeste was ich vom Code her hinbekomme, sieht so aus:

    void lala(int const* in, size_t size, int* out)
    {
        std::map<int,int> vals;
        for ( size_t i=0; i<size; i++ )
            ++ vals[ in[i] ];
        for ( map<int,int>::iterator iter=vals.begin(); iter!=vals.end(); iter++ )
            *(out++) = iter->second;
    }
    


  • also die version von hustbaer hat halt am ende des arrays ein problem weil er ja dann zu wenig zählt...ohne jetzt vorlaut sein zu wollen...

    Ich danke euch allen - aber ich wollte eigentlich nicht die Kürzeste version - sonder die schnellste 🙂

    aber scheint wohl einher zu gehen....



  • @badestrand...du sortierst vorher nicht nicht wahr?

    ich revidiere gerade die aussage von vorhin dass das von hustbaer nicht stimmt....mein hirn nimmts als korrekt an - nur mein eingabe array zählt am ende zu wenig....ich muss noch mal drüberschauen 🙄 🙄



  • gast_xy schrieb:

    @badestrand...du sortierst vorher nicht nicht wahr?

    std::map sortiert automatisch, hab ich mir einfach zu eigen gemacht ...

    btw, hier meine "schnelle, aber lange" Version:

    void lala( int const* in, size_t in_size, int* out, size_t out_size )
    {
    	struct Duo
    	{
    		int key;
    		int value;
    
    		static void SwapElements( Duo* list, int first, int second )
    		{
    			Duo tmp = list[first];
    			list[first] = list[second];
    			list[second] = tmp;
    		}
    
    		static void Quicksort( int low, int high, Duo* list )
    		{
    			int top = low;
    			int bottom = high - 1;
    			int iPartitionIndex = 0;
    			int iPartitionValue = 0;
    			if ( low < high )
    			{
    				if ( high == (low+1) )
    				{
    					if ( list[low].key >= list[high].key )
    						SwapElements( list, high, low );
    				}
    				else
    				{
    					iPartitionIndex = static_cast<int>((low + high) / 2);
    					iPartitionValue = list[iPartitionIndex].key;
    					SwapElements( list, high, iPartitionIndex );
    					do
    					{
    						while ( (list[top].key<iPartitionValue) && (top<=bottom) )
    							++top;
    						while ( (list[bottom].key>=iPartitionValue) && (top <= bottom))
    							--bottom;
    						if ( top < bottom )
    							SwapElements( list, top, bottom );
    					} while ( top < bottom );
    					SwapElements( list, top, high );
    					Quicksort( low, top-1, list );
    					Quicksort( top+1, high, list );
    				}
    			}
    		}
    	};
    
    	int n = 0;
    	Duo* m = new Duo [ out_size ];
    
    	for ( size_t i=0; i<in_size; ++i )
    	{
    		bool found = false;
    		for ( int j=0; j<n; j++ )
    		{
    			if ( m[j].key == in[i] )
    			{
    				++m[j].value;
    				found = true;
    				break;
    			}
    		}
    		if ( ! found )
    		{
    			m[n].key = in[i];
    			m[n].value = 1;
    			++n;
    		}
    	}
    
    	Duo::Quicksort( 0, n-1, m );
    
    	for ( int i=0; i<n; ++i )
    		out[i] = m[i].value;
    
    	delete[] m;
    }
    


  • KasF schrieb:

    Liefert *__first kein pair<int,int> zurück ?

    Nein, ein pair<const int,int> 😉

    So funktioniert das dann aber auch nicht:

    map<int, int> mappo;
    std::vector< pair<const int,int> > ergebnis;
    
    mappo.insert(make_pair(4,5));
    
    pair<const int,int> eraser(4,5);
    remove_copy(mappo.begin(),mappo.end(),ergebnis.begin(),eraser);
    

    Kann jemand mit remove und ner map ein funkionierendes Beispiel posten.



  • @finix: Ich habs mal mit deinem select2nd probiert.

    template<class T>
    struct select2nd
    {
        typename T::second_type operator()( const T& val )
        {
            return val.second;
        }
    };
    
    int main()
    {
    
        map<int, int> mappo;
    
        mappo.insert(make_pair(4,5));
    
        std::vector<int> result;
        transform(mappo.begin(), mappo.end(), result.begin(), select2nd<map<int, int>::value_type>() );
    
        copy(result.begin(),result.end(),ostream_iterator<int>(cout));
    
    }
    

    "..hat ein Problem festgestellt und muss beendet werden" ???
    Wo ist mein Fehler ?

    Edit: Oh man, ich schreibe in irgendeinen Speicher.

    back_inserter(result);
    //oder
    std::vector<int> result(mappo.size());
    

    schafft natürlich Abhilfe.


Anmelden zum Antworten