2012-04-02 2 views
-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

great. 그것은 내가 기대했던 것보다 쉬웠다 :). 이 알고리즘을 작성하기 시작했을 때 포인터에 대한 경험이 없었기 때문에이 첫 번째 코드는 쓰레기와 같았습니다. 이제는 일하고 수정하기가 매우 쉬웠습니다. 끝난! – 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] 

가 사용하는 표현을 사용할 수 있습니다 일반적으로 원시 C 배열을 전달하는 모든 경우의 vector 객체입니다.

0

처음에는 코드를 형식화하는 법을 배웁니다.

둘째, C++에서 배열은 일반적으로 같은 선언한다 :

std::vector<float> anArray; 

[]를 사용하는 declaraion은 인 (C에서 이상 왼쪽, 만 매우 특별한 경우에 사용하면 한 번 완벽하게 마스터 한 std::vector). push_back을 사용하여 값을 삽입하면 벡터가 자동으로 확장됩니다. 당신 사용 반복자 수 있도록하고 std::vector는, 그것으로 주위 크기를 수행 :

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

또한 경우에 당신은 수치 일을하지 경우 아마도 일반적으로 (그러나 더 관용적 인 반복자를 사용하여 반복 할 수 작업).

마지막으로, 입력이 에 도달하지 못했을 때만 유용합니다 (파일의 끝으로 인한 것인지 아니면 그 밖의 것인지). 뭔가처럼 읽을 수있는 일반적인 관용구은 다음과 같습니다.

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

(나는 이것이 당신이 실제로 첫 번째 루프에서 원하는 것을 가정하여있어 당신이 게시 한 코드에서 , 당신은 단지 임시 변수로 읽어 , 때마다 덮어 쓰기 있지만, 그렇지 않으면 당신은 읽을 값으로 아무것도 없습니다.)

마지막으로, 벡터는 매우 클 수 있습니다하지 않는 한, 오히려 float보다, C++에 double를 사용하는 것이 일반적이다. (그러나 이것은 당신이 처리해야 할 데이터의 총량뿐만 아니라 정밀 당신 필요에 따라 달라집니다.)와 루프가 너무 참고 :

Sp += slot[i]; 

가능성이 크기의 경우 매우 가난 결과를 얻을 수 slot의 값으로 운이 좋다면 slot은 큰 값인 입니다. 예를 들어 float과 같이 값이 범위 인 경우 인 경우 약 3 ~ 4 자릿수의 정밀도 만 가질 수 있으며 첫 번째 값이 10000000이면 다음과 같은 1 보다 작은 값은 0으로 처리됩니다. 일반적으로 부동 소수점 순서를 요약하는 특수 알고리즘이 필요합니다. double을 사용하면 문제가 해결되지만 은 문제를 해결할 수 없습니다.

+0

첫 번째 루프는 파일의 크기를 가져 오는 것만을 목표로하고 나중에 파일의 값을 가져옵니다. 그러나 나는'push_back' 함수를 사용하여 하나의 단일 루프에서 두 가지를 모두 달성 할 수 있었다고 생각합니다. – MarcoBi