Mehrdimensionales Array kopieren



  • Kannst Du vielleicht mal ein Codeschnippsel für die Berechnung posten?



  • Klar kann ich ein Beispiel Posten, aber nur sehr stark vereinfacht. Da steht jetzt keine besondere Logik dahinter, es ist viel mehr eine grobe Struktur der Berechnung, also bitte nicht so sonderlich auf die Keys in der Map oder ähnliches achten. Ich hoffe das Hilft weiter, wenn nicht gebe ich gerne weitere Auskünfte dazu.

    float MyClass::calculate(vector< map<string,float> > myVector)
    {	
    	int i=0, j=0;
    	float fltResult=0;
    
    	//Reihenfolge der Datzensätze bestimmen
    	for(i = myVector.size()-1; i>=1; i--)
    	{
    		for(j=0; j<i; j++)
    		{
    			if(myVector[j]["value_a"]<myVector[j+1]["value_a"])
    			{
    				myVector.swap(myVector[j+1],myVector[j]);
    			}
    		}
    	}
    
    	//Anfangswerte ermitteln
    	float fltA = getAddition(myVector[0]["value_a"]);
    	float fltSum = getAddition(myVector[0]["sum"]);
    	float fltDecrease = getDecrease(myVector[0]["decrease"]);
    
    	//Berechnung durchführen
    	for (i=1; i<myVector.size(); i++){
    		fltDecrease = getDecrease(myVector[i]["decrease"], fltDecrease);
    
    		if(myVector[i]["value_h"]>85){
    			fltDecrease = fltDecrease+myVector[i]["value_y"];
    			fltSum = fltSum-myVector[i]["value_h"];
    		}
    
    		fltResult = fltSum+myVector[i]["value_d"]*(myVector[i]["value_g"]-myVector[i]["value_d"])-fltA;
    		fltA = fltA-myVector[i]["value_i"];
    
    		myVector[i]["value_a"] = myVector[i]["value_h"]+(myVector[i]["value_v"]/3)
    	}
    
    	return fltResult;
    }
    


  • Also, ich würde auf die Map verzichten, und es vielleicht eher so machen:

    struct CalcDataElem
    {
        float value_a;
        float value_d;
        float value_g;
        float value_h;
        float value_i;
        float value_v;
        float value_y;
        float decrease;
        float sum;
    };
    
    typedef std::vector<CalcDataElem> CalcData;
    
    //...
    
    float MyClass::calculate(CalcData myVector) //original nicht aendern->pass by value
    {
        //Funktor sortiert nach value_a
        struct SortBy_value_a
        {
            bool operator()(const CalcDataElem& L, const CalcDataElem& R)
            {   return L.value_a < R.value_a;   }
        } value_aSorter;
    
        //sortieren
        std::sort(myVector.begin(), myVector.end(), value_aSorter);
    
        const float SpecialCase = 85.0f;   //Magic Numbers sind Mist! Sprechende Namen benutzen
        const float SpecialDivider = 3.0f; //s.o.
    
        CalcData::iterator iter = myVector.begin();
        float result           = 0.0f; 
        float currentValueA    = iter->value_a;  //ich weiss nicht, was getAddition tut, daher direkt myVector[0].value_a
        float currentSum       = iter->sum;      //s.o.
        float currentDecrease  = iter->decrease; //s.o. nur fuer getDecrease
    
        while( iter != myVector.end() )
        {
            currentDecrease = getDecrease(iter->decrease, currentDecrease);
            if(iter->value_h > SpecialCase)
            {
                currentDecrease += iter->value_y;
                currentSum      -= iter->value_h;
            }
            result = currentSum + iter->value_d * (iter->value_g - iter->value_d) - currentValueA;
            currentValueA -= iter->value_i;
            iter->value_a = iter->value_h + (iter->value_v / SpecialDivider);
            ++iter;
        }
        return result;
    }
    


  • Hallo Tachyon,

    sieht professionell aus und gefällt mir sehr gut. Ich werde es mal so versuchen und gebe dann eine entsprechende Rückmeldung, kann aber ein paar Tage. Vielen Dank aber schon einmal für die Mühe und das tolle Beispiel.



  • Wenn ich das ganze richtig sehe, muss sich:

    //Funktor sortiert nach value_a
    static struct SortBy_value_a
    {
    	bool operator()(const CalcDataElem& L, const CalcDataElem& R)
    	{   return L.value_a < R.value_a;   }
    } value_aSorter;
    

    außerhalb der Funktion befinden und mit einem "static" erweitert werden, sonst erhalte ich einen Kompiler-Fehler.

    Sonst funktioniert alles bestens und habe einen großen Teil der Software bereits umgestellt, nochmal vielen Dank!



  • Sharpie schrieb:

    Wenn ich das ganze richtig sehe, muss sich:

    //Funktor sortiert nach value_a
    static struct SortBy_value_a
    {
    	bool operator()(const CalcDataElem& L, const CalcDataElem& R)
    	{   return L.value_a < R.value_a;   }
    } value_aSorter;
    

    außerhalb der Funktion befinden und mit einem "static" erweitert werden, sonst erhalte ich einen Kompiler-Fehler.

    Sonst funktioniert alles bestens und habe einen großen Teil der Software bereits umgestellt, nochmal vielen Dank!

    Nö, eigentlich darf es in der Funktion stehen. Was sagt der Compiler denn?


  • Mod

    Tachyon schrieb:

    Sharpie schrieb:

    Wenn ich das ganze richtig sehe, muss sich:

    //Funktor sortiert nach value_a
    static struct SortBy_value_a
    {
    	bool operator()(const CalcDataElem& L, const CalcDataElem& R)
    	{   return L.value_a < R.value_a;   }
    } value_aSorter;
    

    außerhalb der Funktion befinden und mit einem "static" erweitert werden, sonst erhalte ich einen Kompiler-Fehler.

    Sonst funktioniert alles bestens und habe einen großen Teil der Software bereits umgestellt, nochmal vielen Dank!

    Nö, eigentlich darf es in der Funktion stehen. Was sagt der Compiler denn?

    Die Klasse muss außerhalb der Funktion definiert sein.
    , denn lokale Klassen dürfen nicht Templateargument sein (und der sort-Aufruf deduziert ja die Klasse aus dem Argument). Wo das Objekt allerdings definiert wird, ist unerheblich. static ist unnötig, im Zweifelsfall wäre ein anonymer Namensraum vorzuziehen. Falls die Funktion calculate allerdings inline im Header definiert ist, und value_aSorter auf Namensraumebene definiert wird, darf es weder static sein, noch sich in einem anonymen Namensraum befinden, sonst wird die ODR verletzt. Am sinnvollsten und üblich dürfte immer noch sein, das Vergleichsobjekt temporär direkt beim sort-Aufruf zu erzeugen.



  • camper schrieb:

    Die Klasse muss außerhalb der Funktion definiert sein.
    , denn lokale Klassen dürfen nicht Templateargument sein (und der sort-Aufruf deduziert ja die Klasse aus dem Argument). Wo das Objekt allerdings definiert wird, ist unerheblich. static ist unnötig, im Zweifelsfall wäre ein anonymer Namensraum vorzuziehen. Falls die Funktion calculate allerdings inline im Header definiert ist, und value_aSorter auf Namensraumebene definiert wird, darf es weder static sein, noch sich in einem anonymen Namensraum befinden, sonst wird die ODR verletzt. Am sinnvollsten und üblich dürfte immer noch sein, das Vergleichsobjekt temporär direkt beim sort-Aufruf zu erzeugen.

    😕
    Der Typ wird doch nicht aus der Prädikaten-Klasse deduziert, sondern aus dem Iteratoren-Typ.



  • Tachyon schrieb:

    😕
    Der Typ wird doch nicht aus der Prädikaten-Klasse deduziert, sondern aus dem Iteratoren-Typ.

    Der Iterator-Typ wird wohl aus dem Iterator deduziert. Der Typ des Prädikats hat aber mit dem Iterator wenig zu tun.


  • Mod

    Tachyon schrieb:

    Der Typ wird doch nicht aus der Prädikaten-Klasse deduziert, sondern aus dem Iteratoren-Typ.

    template<class RandomAccessIterator, class Compare>
    void sort(RandomAccessIterator first, RandomAccessIterator last,
    Compare comp);
    


  • camper schrieb:

    Tachyon schrieb:

    Der Typ wird doch nicht aus der Prädikaten-Klasse deduziert, sondern aus dem Iteratoren-Typ.

    template<class RandomAccessIterator, class Compare>
    void sort(RandomAccessIterator first, RandomAccessIterator last,
    Compare comp);
    

    Jo, habs auch gerade unter 14.3.1 §2 gefunden. Und Comeau und g++ schlucken das auch einleuchtenderweise tatsächlich nicht.
    MSVC 2008 allerdings schon...


Anmelden zum Antworten