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

Variable length arrays depending on length of file C++

本文关键字:文件 C++ 取决于 数组      更新时间:2023-10-16

我遇到了一个问题,试图将我的算法推广到任何大小的问题。代码正在解决我使用的测试问题,但我不得不手动插入一些数组的长度。接下来,我尝试在两个变量中读取输入文件的长度,但随后我无法在所有代码中使用它们,只能在某些部分中使用。我觉得这是一件很愚蠢的事情,但我对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。我在Mac上用Xcode编程,它说变量长度数组不能在文件范围内声明,我认为这意味着全局变量。我该怎么办?

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

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

然后您可以使用表达式

&myCharArray[0]

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

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

申报

   int     *slot

并将内存分配为

slot = new int[cont_slot];

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

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

float* distanze = new float[length];

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

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

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

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

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

std::vector<float> anArray;

使用[]的声明是C的遗留部分,仅用于非常特殊的情况(一旦你完全掌握了std::vector)。和一个如果使用push_back插入,矢量将自动扩展价值观std::vector携带着它的尺寸,所以你can迭代器使用:

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];

如果CCD_ 12的大小较大,除非你对slot中的值感到幸运。如果值在0.5...1的范围,例如,在几千个值之后float,您只有大约3或4个小数位数的精度,并且如果第一个值恰好是10000000,以下任何小于1的值被视为零。通常,你需要特殊的算法来总结浮点序列。(使用double会有所改善,但不会消除问题。)