可变长度数组取决于文件C ++的长度

时间:2012-04-02 10:37:37

标签: c++ dynamic-allocation

我遇到了一个问题,试图将我的算法推广到任何大小的问题。 代码正在用于我使用的测试问题,但我必须手动插入一些数组的长度。接下来,我尝试在两个变量中读取输入文件的长度,但是后来我无法在我的所有代码中使用它们,只是在某些部分中。我认为这是一个非常愚蠢的事情,但我是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 个答案:

答案 0 :(得分:1)

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

float* distanze = new float[length];

或者更好的是std::vector

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

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

答案 1 :(得分:1)

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

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

然后您可以使用表达式

&myCharArray[0]

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

答案 2 :(得分:1)

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

声明

   int     *slot

并将内存分配为

slot = new int[cont_slot];

并且在使用之后别忘了“删除[]插槽”它..:)

答案 3 :(得分:0)

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

其次,在C ++中,数组通常用以下内容声明:

std::vector<float> anArray;

使用[]的声明是C的遗留物,仅用于 非常特殊的情况(一旦你完全掌握了std::vector)。还有一个 如果使用push_back插入,vector将自动扩展 值。 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 );
}

(我假设这是你在第一个循环中实际需要的东西。 在您发布的代码中,您只需读入一个临时变量, 每次都要覆盖,但不能以其他方式做任何有价值的事情 你看了。)

最后,除非您的矢量可能非常大,否则通常会使用它 C ++中的double,而不是float。 (但这取决于 您需要处理的数据总量以及您的精确度 需要。)注意一个循环:

Sp += slot[i];
如果slot的大小很大,

可能会给出非常糟糕的结果, 除非你对slot中的值感到幸运。如果值在 例如,在几千个值之后,0.5...1的范围 float,你只有大约3或4个十进制数字的精度,如果 第一个值恰好是10000000,任何后续值小于1 被视为零。通常,您需要特殊的算法来总结 浮点序列。 (使用double会改善一些事情,但不会 消除问题。)