سؤال

I'm encountering a problem trying to generalize my algorithm for any-size problems. The code is working for the test problem I used, but I had to insert manually the lenght of some arrays. Next, I've tried reading the lenght of input files in two variables, but then I'm not able to use them in all of my code, but just in some pieces. I think it's quite a stupid thing, but I'm really new to C++ and I'd like to get help. Here's the piece of code:

#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++;
    }
}
....

As you can see, in the main() I count the lenght of input files into cont_prod and cont_slot variables, but then I can't use them in variable declaration. The variable lenght arrays I need have to be global variables 'cuz I need them also in other functions. And also cont_prod and cont_slot need to be global, as I need them in local variable declarations in some functions. Here is one of the functions I need to use them in:

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 is cont_prod and 360 is cont_slot. I'm programming on a Mac in Xcode and it says that variable lenght arrays cannot be declared at file scope, which I think it means as global variables. How can I manage that?

هل كانت مفيدة؟

المحلول

Perhaps declare pointers at file scope and allocate memory dynamically as and when you know the values...

Declare

   int     *slot

and allocate memory as

slot = new int[cont_slot];

and after using dont forget to "delete [] slot" it .. :)

نصائح أخرى

Just focusing on your actual question here: in C++, you create variable length-arrays using std::vector, like this:

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

You can then use the expression

&myCharArray[0]

to use the vector object in all cases where you'd normally pass a raw C array.

Disclaimer: I didn't read the whole question, but it seems to me like you need either a dynamically allocated array:

float* distanze = new float[length];

or, better yet, a std::vector:

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

You can insert values in the vector via distanze.push_back(float) and iterate through it just like it was an array, with operator [].

For starters, you should learn to format your code.

Secondly, in C++, an array is normally declared with something like:

std::vector<float> anArray;

The declaraion using a [] is a left-over from C, and is only used in very special cases (once you've fully mastered std::vector). And a vector will extend itself automatically if you use push_back to insert values. And an std::vector carries its size around with it, so you can iterator using:

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

You can also iterate using iterators, which is more idiomatic in general (but perhaps not in the case where you are doing numerical work).

Finally, std::istream::eof() is really only useful once input has failed (to know whether the failure is due to end of file, or something else). The usual idiom to read would be something like:

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

(I'm supposing that this is what you actually want in the first loop. In the code you've posted, you just read into a temporary variable, overwriting each time, but not otherwise doing anything with the value you read.)

Finally, unless your vectors may be very large, it's usual to use double in C++, rather than float. (But this depends on the total amount of data you need to handle, as well as the precision you need.) Note too that a loop with:

Sp += slot[i];

will likely give very poor results if the size of slot is large, unless you're lucky with the values in slot. If the values are in the range of 0.5...1, for example, after a couple of thousand values, with float, you only have about 3 or 4 decimal digits of precision, and if the first value happens to be 10000000, any following values less than 1 are treated as zero. Typically, you need special algorithms to sum up floating point sequences. (Using double will improve things, but not eliminate the problem.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top