-2

我遇到了一个问题,试图将我的算法推广到任何大小的问题。该代码适用于我使用的测试问题,但我必须手动插入一些数组的长度。接下来,我尝试在两个变量中读取输入文件的长度,但是我无法在我的所有代码中使用它们,而只是在某些部分中使用它们。我认为这是一件很愚蠢的事情,但我对 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() 中,我将输入文件的长度计入 cont_prod 和 cont_slot 变量中,但是我不能在变量声明中使用它们。我需要的可变长度数组必须是全局变量,因为我在其他函数中也需要它们。而且 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

4 回答 4

2

在这里只关注您的实际问题:在 C++ 中,您使用创建可变长度数组std::vector,如下所示:

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

然后您可以使用表达式

&myCharArray[0]

在通常传递原始 C 数组的所有情况下使用向量对象。

于 2012-04-02T10:44:18.860 回答
1

免责声明:我没有阅读整个问题,但在我看来,您需要一个动态分配的数组:

float* distanze = new float[length];

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

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

您可以通过在向量中插入值distanze.push_back(float)并对其进行迭代,就像它是一个数组一样,使用operator [].

于 2012-04-02T10:43:52.743 回答
1

也许在文件范围内声明指针并在您知道值时动态分配内存......

宣布

   int     *slot

并将内存分配为

slot = new int[cont_slot];

使用后不要忘记“删除[]插槽”它.. :)

于 2012-04-02T10:47:31.097 回答
0

对于初学者,您应该学习格式化代码。

其次,在 C++ 中,数组通常声明为:

std::vector<float> anArray;

使用 a 的声明[]是 C 的遗留物,仅在非常特殊的情况下使用(一旦你完全掌握了std::vector)。如果您使用push_back插入值,向量将自动扩展自身。并且 anstd::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会改善问题,但不会消除问题。)

于 2012-04-02T11:24:07.083 回答