2012-04-02 8 views
-2

Ich stoße auf ein Problem bei der Verallgemeinerung meines Algorithmus für Größenprobleme. Der Code funktioniert für das Testproblem, das ich verwendet habe, aber ich musste manuell die Länge einiger Arrays einfügen. Als nächstes habe ich versucht, die Länge der Eingabedateien in zwei Variablen zu lesen, aber dann kann ich sie nicht in meinem gesamten Code verwenden, sondern nur in einigen Stücken. Ich denke, es ist eine ziemlich dumme Sache, aber ich bin wirklich neu in C++ und ich würde gerne Hilfe bekommen. Hier ist das Stück Code:Arrays mit variabler Länge, abhängig von der Länge der Datei C++

#include <fstream> 
#include <iostream> 
#include <time.h> 



using namespace std; 

struct node{ 
int  last_prod; 
int  last_slot; 
float ZL; 
float ZU; 
float g; 
bool fathomed; 
node *next; 
node *padre; 
node *primofiglio; 
}; 

clock_t start, end; 
double cpu_time_used; 


int l=0; 
int cont_slot=0; 
int cont_prod=0; 
float temp_cont; 

float distanze[360];        // dichiarazione variabili 
int  slot[111]; 
int  slot_cum[111]; 
float COIp[111]; 
int  domanda[111]; 
float Zb=9999999999999999;        
float LowerBound(struct node *n); 
float UpperBound(struct node *n); 
float h(struct node *l,struct node *n); 
void creasottolivello(struct node *n); 
void fathRule2(struct node *n); 
void fathRule3(struct node *n); 
void stampaRisultati(struct node *n, ofstream &f); 
int  unFathomedNodes(struct node *n); 
void append(struct node* temp, struct node* n); 
void ricercaOttimo(struct node *n, ofstream &f); 
void calcoloBounds(struct node *n); 

int main(){ 

start = clock(); 

ifstream contdist_file ("/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/dati/distanze.txt" ); // conteggio dati input 


if (!contdist_file.is_open()) {     //conta righe file slot 
} 
else { 
    for(int i=0; !contdist_file.eof(); i++){ 
     contdist_file >> temp_cont; 
     cont_slot++; 
    } 
} 

ifstream contslot_file ("/Users/MarcoBi/Desktop/TESI di LAUREA/Xcode/dati/slot.txt"); 

if (!contslot_file.is_open()) {     //conta righe file prodotti 
} 
else { 
    for(int i=0; !contslot_file.eof(); i++){ 
     contslot_file >> temp_cont; 
     cont_prod++; 
    } 
} 
.... 

Wie Sie in der main() sehen kann ich die Länge von Eingabedateien in cont_prod und cont_slot Variablen zählen, aber dann kann ich sie nicht in Variablendeklaration verwenden. Die variablen Längenarrays, die ich brauche, müssen globale Variablen sein, weil ich sie auch in anderen Funktionen brauche. Und auch cont_prod und cont_slot müssen global sein, da ich sie in lokalen Variablendeklarationen in einigen Funktionen brauche. Hier ist eine der Funktionen, die ich brauche sie in verwenden:

float LowerBound(struct node *n){    //funzione LowerBound 
int S[111]; 
int Sp=0; 
float d[111]; 
float dmin[111]; 
float D; 
float LB; 

for(int i=n->last_prod;i<111;i++){ 
    Sp=Sp+slot[i]; 
} 
for(int i=0;i<111;i++){      //Calcolo S_pigreco 
    S[i]=0; 
} 

if(n->last_prod==0){       //condizione necessaria per nodo radice 
    S[0]=slot[0];  
    for(int i=n->last_prod +2;i<111;i++){ 
     for(int j=n->last_prod +1;j<=i;j++){ 
      S[j]=S[j-1]+slot[j]; 
     } 
    } 
} 
else{ 
    for(int i=n->last_prod +1;i<111;i++){ 
     for(int j=n->last_prod;j<=i;j++){ 
      S[j]=S[j-1]+slot[j]; 

     } 
    } 
} 
S[110]=S[109] + slot[110]; 

//calcolo somma distanze da slot j+1 a q 
for(int i=0;i<111;i++){ 
    d[i]=0; 
} 

for(int j=n->last_prod;j<111;j++){ 
    for(int i=n->last_slot; i < n->last_slot +S[j]; i++){ 
     d[j]=d[j]+distanze[i]; 
    } 
} 

//calcolo dmin_pigreco 
for(int i=n->last_prod; i<111; i++){ 
    dmin[i]= d[i]/S[i]; 
} 

D=0; 
for(int i=n->last_prod; i<111; i++){ 
    D=D+dmin[i]*domanda[i]; 
} 
LB=n->g+2*D;           
return LB;         
} 

111 ist cont_prod und 360 ist cont_slot. Ich programmiere auf einem Mac in Xcode und es besagt, dass Arrays mit variabler Länge nicht im Dateibereich deklariert werden können, was meiner Meinung nach globale Variablen bedeutet. Wie kann ich das schaffen?

+4

Das ist ein riesiger Stück Code. Könnten Sie bitte alles entfernen, was für Ihre Frage nicht wichtig ist? – celtschk

+0

Sie haben geschrieben: Die Variablen length arrays, die ich brauche, müssen globale Variablen sein, weil ich sie auch in anderen Funktionen brauche. Beachten Sie, dass ein viel besserer Weg, um diese Situation zu behandeln, wäre, die benötigten Arrays an jede Funktion als Argumente zu übergeben. Es vermeidet die Notwendigkeit globaler Variablen, und die Funktionssignaturen drücken die Abhängigkeiten deutlich aus (neben anderen netten Vorteilen). –

Antwort

1

Vielleicht Zeiger auf Dateigültigkeitsbereich deklarieren und zuweisen Speicher dynamisch wie und wann Sie die Werte kennen ...

Deklarieren

int  *slot 

und weisen Speicher als

slot = new int[cont_slot]; 

und nach der Verwendung vergiss nicht, "[slot] es zu löschen .. :)

+0

Sorry geändert .. –

+0

großartig. das war einfacher als ich erwartet hatte :). Als ich anfing, diesen Algorithmus zu schreiben, hatte ich keine Erfahrung mit Zeigern, also war dieser allererste Code wie Mist. Jetzt funktioniert es und war sehr einfach zu modifizieren, thx. ERLEDIGT! – MarcoBi

1

Haftungsausschluss: Ich habe die ganze Frage nicht gelesen haben, aber es scheint mir, wie Sie entweder eine dynamisch zugewiesene Array benötigen:

float* distanze = new float[length]; 

oder, besser noch, ein std::vector:

std::vector<float> distanze; // <-- this is the proper C++ way 

Sie können Werte in den Vektor über distanze.push_back(float) einfügen und durchlaufen, genau wie es ein Array war, mit operator [].

1

einfach auf Ihre eigentliche Frage konzentriert sich hier: in C++, Sie mit variabler Länge-Arrays erstellen std::vector verwenden, wie folgt aus:

std::vector<char> myCharArray(n * 1000); 

Sie können dann den Ausdruck

&myCharArray[0] 

verwenden die Vektorobjekt in allen Fällen, in denen Sie normalerweise ein rohe C-Array übergeben würden.

0

Für den Anfang, Sie Shou lch lerne, deinen Code zu formatieren.

Zweitens in C++ ist ein Array normalerweise mit so etwas wie erklärt:

std::vector<float> anArray; 

Die declaraion ein [] verwendet, ist eine übriggebliebene von C, und nur in ganz besonderen Fällen verwendet wird (wenn Sie habe voll gemeistert std::vector). Und ein Vektor verlängert sich automatisch, wenn Sie push_back verwenden, um Werte einzufügen. Und ein std::vector trägt seine Größe, um mit ihm, so dass Sie Iterator können mit:

for (int i = 0; i != v.size(); ++ i) { 
    // use `v[i]` here... 
} 

Sie können auch Iteratoren iterieren verwenden, die im allgemeinen mehr idiomatischen (aber vielleicht nicht in dem Fall, dass Sie numerische tun Arbeit).

Schließlich ist std::istream::eof() wirklich nur nützlich, wenn die Eingabe fehlgeschlagen ist (um zu wissen, ob der Fehler aufgrund des Endes der Datei oder etwas ist sonst). Das übliche Idiom wäre zu lesen so etwas wie:.

float value; 
while (contdist_file >> value) { 
    distanze.push_back(value); 
} 

(Ich bin die Annahme, dass das ist, was man eigentlich in der ersten Schleife will Im Code, den Sie geschrieben haben, lesen Sie einfach in eine temporäre Variable , jedes Mal überschrieben wird, aber sonst nicht mit dem Wert etwas zu tun Sie lesen.)

Schließlich, es sei denn Ihre Vektoren sehr groß sein können, ist es üblich double in C++ zu verwenden, anstatt float. (Aber das hängt von der Gesamtmenge an Daten, die Sie behandeln müssen, sowie die Präzision Sie Notwendigkeit.) Beachten, dass eine Schleife mit:

Sp += slot[i]; 

wird wahrscheinlich geben sehr schlechte Ergebnisse, wenn die Größe slot ist groß, , wenn Sie Glück mit den Werten in slot haben. Wenn die Werte im Bereich von 0.5...1 liegen, zum Beispiel nach ein paar tausend Werten, haben Sie mit float nur etwa 3 oder 4 Dezimalstellen der Genauigkeit, und wenn der erste Wert zufällig 10000000 ist, folgt jede folgende Werte kleiner als 1 werden als Null behandelt. In der Regel benötigen Sie spezielle Algorithmen, um Fließkomma-Sequenzen zusammenzufassen. (Mit double wird Dinge zu verbessern, aber nicht das Problem zu beseitigen.)

+0

Die erste Schleife zielt nur darauf ab, die Größe der Datei zu bekommen, danach bekomme ich auch die Werte in der Datei. Aber ich denke, ich könnte beides in einer einzigen Schleife mit der 'Push_back'-Funktion erreichen – MarcoBi

Verwandte Themen