Datenstrukturen: Namen variabel definieren in for-loop



  • Hallo,

    ich bin gerade dabei eine Matlabsimulation in C zu übertragen, leider ist C für mich neu, sodass ich über sämtliche Anfängerfehler stolpere.

    Mein aktuelles Problem: im Folgenden habe ich ein string array year_str definiert, welches ich gerne als Grundlage für die Definition von Datenstrukturen verwenden möchte (num_years wurde bereits vorher definiert und hängt von importierten csv Daten ab):

    for (int y=0; y<num_years;++y)
    	{
    		years[y]=2015+y;
    
    	   // now: definition of string array year_str:                     
    		ostringstream convert;
    		convert<<years[y];
    		year_str[y]=convert.str();
    
    	}
    

    Sprich: in year_str habe ich nun meine Jahre gespeichert. Diese möchte ich nun verwenden, um verschiedene Datenstrukturen zu definieren (z.B. für die structure energy habe ich dann die zugehörigen arrays mit den Bezeichnungen 2015, 2016,...).
    In Matlab würde ich das leicht innerhalb der for-Schleife mit energy.(year_str{y,1})= "..." realisieren. Könnt ihr mir einen Tipp geben wie ich das Ganze in C umsetzen kann?

    Liebe Grüße
    Rike



  • Dein Programm ist kein C, sondern C++. Ich nehme an, dass du weiter in C++ arbeiten willst und werde entsprechend antworten. Andernfalls wird das ganze wesentlich komplizierter.

    Es gibt wahrscheinlich eine idiomatischere Lösung, aber wenn du energy.(year_str{y,1}) einfach 1:1 übersetzen willst, kannst du eine map benutzen:

    #include<map>
    using namespace std;
    ...
    map<string, string> energy;
    
    energy["bla"] = "blub";
    energy[year_str[y]] = " ... ";
    ...
    

    Denkbar wäre natürlich auch eine map<int, string> , da ich nicht ganz einsehe, warum man das Jahr erst in einen String umwandeln sollte.



  • Hi Bashar,
    erstmal vielen Dank für Deine schnelle Antwort! Wie Du merkst, bin ich Neuling in C/C++ und gebe Dir Recht, ja ich möchte das Ganze in C++ umsetzen (ich werde künftig meine Fragen im entsprechenden Unterforum posten;)).

    Das Stichwort map ist auf jeden Fall ein guter Hinweis.

    Ich weiß momentan noch nicht, wie ich meine Simulation am besten C++ aufsetzen soll. In Matlab steht diese soweit, doch dadurch, dass ich stets während der Laufzeit neue Arrays definiere (deren Größe erst während der Simulation bekannt werden ...und die Anzahl und Bezeichnung eben auch erst dann (u.a. abh. von num_year-Input sowie von Ergebnissen aus dem jeweiligen Vorjahr = Ergebnisse aus der vorigen loop-Iteration)) und an diesen weitere Berechnungen durchführe (sowohl einfache Matrixoperationen, Permutationen, Interpolationen von Daten, Abfragen nach bestimmten Werten...) komme ich nun in C++ überhaupt nicht weiter, in Matlab kann ich ohne weiteres neue Arrays während der Simulation definieren (size wird dann über eine zuvor kalkulierte Variable definiert z.b. energy=zeros(num_years)). Das Gleiche Problem habe ich wenn ich arrays während der Simulation definieren möchte (aber map scheint ja schon eine gute Idee von Dir zu sein!)
    . Kannst Du mir noch einen Tipp geben, wonach ich konkret schauen muss, um das entsprechend in C++ umsetzen zu können? Aktuell tappe ich völlig im Dunkeln:/.....

    Liebe Grüße
    Rike
    PS: Ich freue mich natürlich auch über Hinweise von anderen Usern :-)!



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (alle ISO-Standards) in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Rike20 schrieb:

    . Kannst Du mir noch einen Tipp geben, wonach ich konkret schauen muss, um das entsprechend in C++ umsetzen zu können? Aktuell tappe ich völlig im Dunkeln:/.....

    Ich hab nicht wirklich verstanden, welches Problem du noch hast. Könntest du ein bisschen konkreter werden?



  • Rike20 schrieb:

    In Matlab steht diese soweit, doch dadurch, dass ich stets während der Laufzeit neue Arrays definiere (deren Größe erst während der Simulation bekannt werden ...und die Anzahl und Bezeichnung eben auch erst dann (u.a. abh. von num_year-Input sowie von Ergebnissen aus dem jeweiligen Vorjahr = Ergebnisse aus der vorigen loop-Iteration)) und an diesen weitere Berechnungen durchführe (sowohl einfache Matrixoperationen, Permutationen, Interpolationen von Daten, Abfragen nach bestimmten Werten...) komme ich nun in C++ überhaupt nicht weiter, in Matlab kann ich ohne weiteres neue Arrays während der Simulation definieren (size wird dann über eine zuvor kalkulierte Variable definiert z.b. energy=zeros(num_years)).

    Ein Satz mit 714 Zeichen, davon mehr als die Hälfte in Klammern...
    Und noch über 100 Zeichen in einer 2. Klammerebene...
    Ernst jetzt?

    Davon abgesehen...

    Wie Bashar schon geschrieben hat verwendet man in C++ normalerweise keine Maps mit Strings als Key um Daten abzuspeichern, wenn der Key in wirklichkeit eine Zahl ist die bloss als String formatiert wird.

    Und ich verstehe, wie Bashar, auch nicht wirklich wo der Schuh jetzt wirklich drückt.

    Kannst Du mir noch einen Tipp geben, wonach ich konkret schauen muss, um das entsprechend in C++ umsetzen zu können? Aktuell tappe ich völlig im Dunkeln:/.....

    Du brauchst als erstes mal eine Beschreibung deiner Datenstruktur. Also: beschreibe sie uns.



  • Der ist noch besser - 945 Zeichen ohne Absatz. Wer soll sich sowas durchlesen?

    Ich weiß momentan noch nicht, wie ich meine Simulation am besten C++ aufsetzen soll. In Matlab steht diese soweit, doch dadurch, dass ich stets während der Laufzeit neue Arrays definiere (deren Größe erst während der Simulation bekannt werden ...und die Anzahl und Bezeichnung eben auch erst dann (u.a. abh. von num_year-Input sowie von Ergebnissen aus dem jeweiligen Vorjahr = Ergebnisse aus der vorigen loop-Iteration)) und an diesen weitere Berechnungen durchführe (sowohl einfache Matrixoperationen, Permutationen, Interpolationen von Daten, Abfragen nach bestimmten Werten...) komme ich nun in C++ überhaupt nicht weiter, in Matlab kann ich ohne weiteres neue Arrays während der Simulation definieren (size wird dann über eine zuvor kalkulierte Variable definiert z.b. energy=zeros(num_years)). Das Gleiche Problem habe ich wenn ich arrays während der Simulation definieren möchte (aber map scheint ja schon eine gute Idee von Dir zu sein!)

    Zu den geklammerten Klammern geb ich jetzt keinen Kommentar ab.
    Ziemlich übersichtlich die ganze Geschichte.

    EDIT #3:
    Etwas bösen Kommentar von EDIT #2 entfernt.


  • Mod

    Ich glaube, der Threadersteller sollte mittlerweile mitbekommen haben, dass sein Schreibstil einer guten Antwort im Weg steht. Das muss ihm jetzt nicht jeder einzelne Leser noch einmal sagen. Entweder kommt vom Threadersteller noch eine lesbare, verständliche Problembeschreibung; oder eben nicht und die Frage bleibt dann leider unbeantwortbar.



  • Ich wollte zwar nur ein kurzes, illustratives Beispiel posten, aber, ihr wisst schon, Feature Creep und so … 😉

    #include <vector>
    #include <string>
    #include <random>
    #include <chrono>
    #include <iostream>
    #include <cstddef>
    
    struct ArrayMitBeschreibung
    {		
    	std::vector<double> Werte;
    		//Für Simulationsdaten vermutlich geeignet
    	std::string Beschreibung;
    };
    
    ArrayMitBeschreibung DatenErzeugen(std::size_t Anz_Werte, unsigned Startwert)
    {
    	class Datenquellentyp
    		{
    			std::default_random_engine Zahlenquelle;
    			std::normal_distribution<> Verteilungsumformer;
    			public:
    			Datenquellentyp(unsigned Startwert)
    				:Zahlenquelle(Startwert), Verteilungsumformer(6, 5)
    				{}
    			double WertErzeugen()
    			{
    				double Wert;
    				do
    					Wert = Verteilungsumformer(Zahlenquelle);
    					while(Wert < 0 || Wert > 12);
    				return Wert;
    			}
    		}
    		Datenquelle(Startwert);
    	ArrayMitBeschreibung Daten;
    	Daten.Beschreibung = "Bewertung des Geschmacks der Tofuburger";
    	for(unsigned AnzBisher = 0; AnzBisher < Anz_Werte; ++AnzBisher)
    		Daten.Werte.push_back(Datenquelle.WertErzeugen());
    	return Daten; //NRVO wird's richten
    }
    
    void DatenMischen(ArrayMitBeschreibung& Daten)
    {
    	auto& Werte = Daten.Werte;
    		//Jede Operation auf Werte wirkt nun auf Daten.Werte
    		//Also in diesem Fall direkt auf das Array aus der Main,
    		//da es per Referenz übergeben wird
    	double Puffer;
    		//Besser wäre es, den Typ automatisch bestimmen zu lassen
    	std::size_t Idx_A = 0;
    	std::size_t Idx_B = Werte.back();
    	for(unsigned Zlr = 0; Zlr < 5*Werte.size(); ++Zlr)
    	{
    		//Werte annähernd zufällig durchtauschen
    		Idx_A = static_cast<std::size_t>((Werte[Idx_A] + 1) *
    			Werte.size()) % Werte.size();
    		Idx_B = static_cast<std::size_t>((Werte[Idx_B] + 1) *
    			2 * Werte.size()) % Werte.size();
    			//Beschwert euch bei dem Typen, der meinte, es wäre total
    			//toll Casts per Textsuche finden zu können ...
    		Puffer = Werte[Idx_A];
    		Werte[Idx_A] = Werte[Idx_B];
    		Werte[Idx_B] = Puffer;
    	}
    }
    
    int main()
    {
    	unsigned Startwert_Simulation =
    		std::chrono::system_clock::now().time_since_epoch().count();
    	unsigned Anzahl_Werte = ((Startwert_Simulation % 419) + 13) / 15;
    	ArrayMitBeschreibung Daten =
    		DatenErzeugen(Anzahl_Werte, Startwert_Simulation);
    	DatenMischen(Daten);
    		//Die Daten sind zwar schon zufällig, aber so wird's
    		//sicherlich besser ;)
    	//Die Daten rausschreiben
    	std::cout << Daten.Beschreibung << ": " << '\n';
    	for(std::size_t Idx = 0; Idx < Daten.Werte.size(); ++Idx)
    		std::cout << Daten.Werte[Idx] << '\n';
    }
    

    Da wird eigentlich alles gezeigt, was du brauchst.
    Generell, und kürzer:

    std::vector<int> T; //Ein Array von Ints
    T.push_back(17); //Element hinzufuegen
    std::vector<std::vector<int>> B; //Ein Array aus Arrays von Ints
    B.push_back(T); //Und dasselbe, Element dazu (diesmal natürlich ein Array)
    

    Wenn der Compiler keinen Speicher für Variablen reservieren kann (z.B. weil zur Übersetzungszeit noch gar nicht bekannt ist, wie viele Elemente die Arrays haben werden), dann muss man sich selbst darum kümmern, dass es irgendwo Speicherplatz für sie gibt. Das ist bei Matlab vielleicht anders (ich kenne Matlab nicht, aber es ist bei vielen Skriptsprachen so).
    Der Vector übernimmt das für einen – es fordert automatisch genug Speicher an (wenn man push_back verwendet, nicht bei Zugriffen mit dem Indexoperator (den eckigen Klammern)!), gibt ihn sicher wieder frei und hält den Zeiger auf die Elemente, verwaltet also die Information, wo sie im Speicher liegen.
    Schau dir auch mal in einer C++-Referenz deiner Wahl die Beschreibungen der Funktionen reserve und resize des vectors an, die könnten dir noch helfen.


Anmelden zum Antworten