2012-04-02 7 views
-2

任意のサイズの問題に対してアルゴリズムを一般化しようとして問題が発生しました。 私が使用したテストの問題のコードが動作していますが、いくつかの配列の長さを手動で挿入する必要がありました。次に、私は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++; 
    } 
} 
.... 

あなたが見ることができるように、メイン()私はcont_prodとcont_slot変数に入力ファイルのな長さを数えるが、その後、私は、変数の宣言でそれらを使用することはできません。私が必要とする可変長配列は、他の関数でも必要なグローバル変数でなければなりません。また、cont_prodとcont_slotは、グローバル変数である必要があります。なぜなら、いくつかの関数でローカル変数宣言でそれらを必要とするからです。 は、ここで私は、それらを使用する必要がある機能の一つである:cont_prodは

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で、360がcont_slotです。 私はXcodeのMacでプログラミングしていますが、可変長配列はファイルスコープで宣言できないと言います。これはグローバル変数として意味すると思います。 これをどのように管理できますか?

+4

これは膨大なコードです。あなたの質問に不可欠ではないすべてを削除してください。 – celtschk

+0

あなたは '私が必要とする可変長配列はグローバル変数でなければなりません。他の関数でも必要です。 'この状況を処理するもっと良い方法は、必要な配列を引数として各関数に渡すことです。これはグローバル変数の必要性を避け、関数シグネチャは(他の優れた利点の中でも)依存関係を明確に表現します。 –

答えて

1

おそらく、ファイルスコープでポインタを宣言して動的にメモリを割り当て、あなたが値を知っているとき...

int  *slot 

を宣言し、

slot = new int[cont_slot]; 

とし、使用後にメモリを割り当てます"[スロット]を削除することを忘れないでください:) ..

+0

申し訳ありません。 –

+0

素晴らしいです。それは私が期待したよりも簡単だった:)。私がこのアルゴリズムを書こうとしたとき、私はポインターでの経験がなかったので、この最初のコードは駄目のようでした。今、それは働いていて、変更するのが非常に簡単でした。完了! – MarcoBi

1

免責事項:、std::vectorまたは、いっその

float* distanze = new float[length]; 

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] 

を使用する式を使用することができますvectorオブジェクトは通常、生のC配列を渡すすべての場合に使用されます。

0

はじめに、あなたのコードをフォーマットすることを学びます。

第二に、C++で、配列は、通常のようなもので宣言されています。

std::vector<float> anArray; 

[]を使用してdeclaraionがCから左オーバーで、かつ唯一の 非常に特別な場合に使用されます(一度完全にマスターされたstd::vector)。 push_backを使用して 値を挿入すると、 ベクトルが自動的に拡張されます。

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

をまた、あなたは数値行っている場合には より一般的に慣用である、イテレータを使用して反復(おそらくことはできません。 を使用してイテレータことができますが、SOおよびstd::vectorは、それを周りのサイズを運びます作業)。

最後に、std::istream::eof()が入力さ が失敗した後、実際にのみ有用である(故障がファイルの終わり、または何か他の によるものであるかどうかを知るために)。あなただけの一時的な変数に読み込む、

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

(私は、これはあなたが実際に最初のループで欲しいものであることを想定していますあなたが投稿したコードで :読むために通常のイディオムは次のようなものになるだろうあなたのベクトルが非常に大きいかもしれない限り、 たびに上書きし、それ以外はあなたが読ん値 で何もしていない。)

は最後に、それはむしろfloatよりも、C++で doubleを使用するのが一般的です。 (しかし、これはあなたが処理するために必要なデータの 総量だけでなく、精度あなた 必要性に依存します。)とのループことにも注意してください:の大きさならば

Sp += slot[i]; 

はおそらく非常に悪い結果が得られますslotという値で運が良ければ、slotは大きく、 です。たとえば、 の範囲が0.5...1の場合、たとえば、数千の値の後に floatとすると、約3〜4桁の精度しかなく、 の場合、最初の値は10000000になります。 1 より小さい値はゼロとして扱われます。通常、浮動小数点シーケンス を要約する特別なアルゴリズムが必要です。 (doubleを使用すると改善されますが、 は問題を解決しません)。

+0

最初のループは、ファイルのサイズを取得することを目的としています。その後、ファイル内の値も取得します。しかし、私は 'push_back'関数を使って一つのループで両方を達成できると思います – MarcoBi