2012-04-02 264 views
-2

我遇到了一個問題,試圖將我的算法推廣到任意大小的問題。 該代碼正在爲我使用的測試問題工作,但我不得不手動插入某些數組的長度。接下來,我試着在兩個變量中讀取輸入文件的長度,但後來我無法在我的所有代碼中使用它們,但只是在一些片段中。我認爲這是一件相當愚蠢的事情,但我對C++非常陌生,我希望得到幫助。 下面是一段代碼:取決於文件長度的可變長度數組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++; 
    } 
} 
.... 

正如你所看到的,在main()我計數輸入文件的lenght到cont_prod和cont_slot變量,但我不能在變量聲明中使用它們。我需要的變量長度數組必須是全局變量'cuz我也需要它們在其他函數中。而且cont_prod和cont_slot需要是全局的,因爲我需要它們在某些函數的局部變量聲明中。 這裏是我需要使用它們的功能之一:

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 cont_prod和360是cont_slot。 我在Xcode上的Mac上進行編程,它說變量長度數組不能在文件範圍聲明,我認爲它意味着全局變量。 我該如何管理?

+4

這是一大塊代碼。你能否刪除對你的問題不重要的一切? – celtschk 2012-04-02 10:44:06

+0

你寫了'我需要的變量長度數組必須是全局變量'因爲我需要他們也在其他函數中。請注意,處理這種情況的更好方法是將所需的數組作爲參數傳遞給每個函數。它避免了對全局變量的需求,並且函數簽名清楚地表達了依賴關係(以及其他很多優點)。 – 2012-04-02 10:46:14

回答

1

或許聲明在文件範圍內指針和動態分配內存,當你知道值...

聲明

int  *slot 

和分配內存作爲

slot = new int[cont_slot]; 

和使用後不要忘記「刪除[]插槽」它.. :)

+0

很抱歉修改.. – 2012-04-02 10:53:50

+0

太棒了。這比我預期的要容易:)。當我開始編寫這個算法時,我沒有指針的使用經驗,所以這第一段代碼就像廢話一樣。現在它正在工作,很容易修改,thx。 DONE! – MarcoBi 2012-04-02 12:14:57

1

聲明:我沒有閱讀的整個問題,但像你需要使用一個動態分配的數組,在我看來:

float* distanze = new float[length]; 

,或者更好的是,一個std::vector

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

您可以通過distanze.push_back(float)在矢量中插入值並像遍歷它一樣通過operator []

1

只需專注於您的實際問題在這裏:在C++中,將使用std::vector可變長度的陣列,像這樣:

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

然後,您可以使用表達式

&myCharArray[0] 

使用在所有的情況下,你通常會傳遞一個原始C數組。

0

對於初學者,你守ld學會格式化你的代碼。

其次,在C++中,數組通常與類似聲明:

std::vector<float> anArray; 

使用[]的declaraion是一個遺留的從C,並且僅在 非常特殊的情況下使用(一旦你已經完全掌握了std::vector)。如果使用push_back插入 值,則 矢量將自動延伸。和std::vector圍繞承載它的大小與它,所以你 可以迭代器使用:

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

您還可以循環使用迭代器,這是更地道一般 (但也許不是的情況下,你正在做的數值工作)。

最後,std::istream::eof()真的只有一次輸入具有 未能有用的(要知道故障是否是由於文件的末尾,或一些其他 )。通常的成語閱讀會是這樣的:

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

(我假設這是你真正想要在第一循環什麼 在你發佈的代碼,你剛纔讀入一個臨時變量, 每次覆蓋,而不是其他做與 你讀的任何有價值的東西。)

最後,除非你的載體可能是非常大的,這是通常使用 double在C++中,而不是float。 (但是,這取決於數據需要處理 總量,以及精密你 需要。)還要注意,用一個循環:

Sp += slot[i]; 

可能會產生非常糟糕的結果,如果大小slot很大, ,除非你幸運地用slot中的值。例如,如果數值在0.5...1的範圍內,例如,在幾千個數值之後,使用 float,則只有大約3或4個精度的十進制數字,並且如果 的第一個值恰好爲10000000,則以下任何值小於1 的值被視爲零。通常情況下,您需要特殊的算法來總結浮點序列 。 (使用double會改善的東西,但不是 可以消除此問題。)

+0

第一個循環只是爲了獲得文件的大小,然後我會得到文件中的值。但我想我可以使用'push_back'函數在一個單一的循環中實現 – MarcoBi 2012-04-02 11:56:26