Titlul: CodeBlocks
Scris de: Simoiu Robert din Iunie 19, 2010, 19:05:10
Am o eroare tare ciudata : rulez un program si imi cicleaza. Trimit pe infoarena, iau 100 pct. Dau la un prieten de pe MinGW, si ii da bine, si cand ii dau la altul tot pe Code Blocks, are aceeasi eroare. Care sa fie problema ? [LE] Uite aici codul : # include <fstream> # include <cstring> # include <cmath> using namespace std;
#define MAX 105
int N[MAX],cnt[MAX],i[MAX]; int j; char c[MAX];
ifstream f("free.in"); ofstream g("free.out");
void atrh (int A[], int B[]) // A <- B { for (int i = 0; i <= B[0]; ++i) A[i] = B[i]; }
void add (int A[], int B[]) // A <- A + B { int i, t = 0;
for (i = 1; i <= A[0] || i <= B[0] || t; i++, t /= 10) A[i] = ( t += ( i <= A[0] ? A[i] : A[i] = 0 ) + ( i <= B[0] ? B[i] : B[i] = 0 ) ) % 10;
A[0] = i - 1; }
void sub (int A[], int B[]) // A <- A - B, A >= B { int i, t = 0; for (i = 1; i <= A[0]; i++) A[i] += ( t = ( A[i] -= ( i <= B[0] ? B[i] : B[i] = 0 ) + t ) < 0 ) * 10; for (; A[0] > 1 && !A[A[0]]; A[0]--); }
inline int comp (int A[], int B[]) // A ? B , ? == <, >, = { while (A[0] && !A[A[0]]) A[0]--; while (B[0] && !B[B[0]]) B[0]--;
if (A[0] < B[0]) return -1; else if (A[0] > B[0]) return 1; for (int i = A[0]; i > 0; --i) if (A[i] < B[i]) return -1; else if (A[i] > B[i]) return 1; return 0; }
void atr (int A[], long long X) // A[] <- X { for ( A[0] = 0; X ; X /= 10) A[++A[0]] = X % 10; }
void atr0 ( int A[] ) { A[0] = 0; }
void mulmare (int A[], int B[]) // A <- A * B { int i, j, t, C[MAX]; // C <- A * B
memset(C, 0, sizeof(C));
for (i = 1; i <= A[0]; i++) { for (t = 0, j = 1; j <= B[0] || t; j++, t /= 10) C[i + j - 1] = ( t += C[i + j - 1] + A[i] * B[j] ) % 10; if ( i + j - 2 > C[0] ) C[0] = i + j - 2; }
memcpy(A, C, sizeof(C)); // A <- C }
void Shr (int A[], int Count) // A <- A / ( 10 * Count ) { memmove ( &A[1], &A[Count + 1], sizeof(int) * ( A[0] - Count ) );
A[0] -= Count; }
void Shl (int A[], int Count) // A <- A * ( 10 * Count ) { memmove ( &A[Count + 1], &A[1], sizeof(int) * A[0] ); memset ( &A[1], 0, sizeof(int) * Count );
A[0] += Count; }
void imp (int A[], int B) // A[] <- A[] / B { int i, t = 0; for (i = A[0]; i > 0; i--, t %= B) A[i] = (t = t * 10 + A[i]) / B; for (; A[0] > 1 && !A[A[0]]; A[0]--); }
void impmare (int A[], int B[], int C[]) // C <- A * B rest R { int R[MAX];
R[0] = 0, C[0] = A[0];
for (int i = A[0]; i ; i--) { Shl (R, 1), R[1] = A[i];
for (C[i] = 0; comp(B,R) != 1 ; ++C[i], sub(R, B)) ; }
for (; !C[C[0]] && C[0] > 1 ; C[0]--); } void mul (int A[], int B) // A[] <- A[] * B { int i, t = 0; for (i = 1; i <= A[0] || t; i++, t /= 10) A[i] = (t += ( i <= A[0] ? A[i] : A[i] = 0 ) * B) % 10;
A[0] = i - 1; }
void citire(int x[],char a[]) { x[0]=strlen(a); for ( int i = x[0] -1; i >= 0; --i ) x[i+1]=a[x[0]-i-1] - '0'; } void write( int A[] ) { if ( A[0] == 0 ) g << "0"; else for (int i = A[0]; i ; --i) g << A[i]; g << "\n"; } void radical_2 ( int A[], int B[] ) { int AUX = 0 , i; int C[MAX], D[MAX], E[MAX], F[MAX];
if ( A[0] & 1 ) AUX = A[A[0]], i = A[0] - 1; // formez prima pereche else AUX = A[A[0]] * 10 + A[A[0] - 1], i = A[0] - 2;
int aux = (int) sqrt(AUX) ; // aflu nr. cel mai apropiat de prima pereche
atr (B, aux); // atribui rezultatului nr. aflat anterior
if ( A[0] == 1 || A[0] == 2) return ; // daca nr. are 1, 2 cifre, opresc
AUX -= aux * aux; // fac scaderea
atr(E, AUX), Shl(E, 1), atr(F, A[i]), add(E, F); // E = AUX, E *= 10, E += A[i]; // adica formez noul numar, adaugand urm. pereche de cate 2 cifre Shl(E, 1), atr(F, A[i - 1]), add(E, F); // E *= 10, E += A[i - 1]; // la fel, formez noul numar adaugand cea de-a doua cifra atrh(C, E), atrh(F, B), mul(F, 2), atrh(E, F); // dublez pe E
i -= 2; // scad 2 unitati, adica cele 2 cifre atribuite
atrh(D, C), Shr(D, 1), impmare(D, E, D); // aici scap de ultima cifra a nr. si o impart la E
int U[] = {1, 9}; // vector auxiliar ce reprezinta cifra 9 int Z[] = {1, 1}; // vector auxiliar ce reprezinta cifra 1
if (comp(D, U) == 1) atr(D, 9); // daca cumva ultima cifra pe care trebuie sa o adaugam la // rezultat e > 9, atunci ii atribuim valoarea maxima, 9 Shl(E, 1), add(E, D), mulmare(E, D); // E *= 10, E += D, E *= D // adica adaug la E cifra D si inmultesc nr. format cu D while ( comp(E, C) == 1 ) // daca E > C, adica ca si numarul format din adaugarea perechilor de cate 2 cifre sub(D, Z), atrh(F, B), mul(F, 2), atrh(E, F), Shl(E, 1), add(E, D), mulmare(E, D); // atunci refac numarul, adica scad o unitate la numarul D si refac operatiile sub(C, E); // fac scaderea, adica numarul format E il scad din C, care a fost numarul format din ad. celor 2 cifre
Shl(B, 1), add(B, D); // B *= 10, B += D , adica adaug la rezultat cifra D
for (i = i; i ; i -= 2) // aici merg cu un for care reprezinta pozitia de unde voi adauga cele 2 cifre { atr(E, A[i]), atr0(F), Shl(F, 1), add(F, E); // de aici operatiile se reiau atr(E, A[i - 1]), Shl(F, 1), add(F, E);
Shl(C, 2), add(C, F), atrh(F, B), mul(F, 2), atrh(E, F);
atrh(D, C), Shr(D, 1), impmare(D, E, D);
if (comp(D, U) == 1) atr(D, 9);
Shl(E, 1), add(E, D), mulmare(E, D);
while ( comp(E, C) == 1 ) sub(D, Z), atrh(F, B), mul(F, 2), atrh(E, F), Shl(E, 1), add(E, D), mulmare(E, D);
sub(C, E);
Shl(B, 1), add(B, D); } }
int main() { f >> c;
citire(N,c);
radical_2(N,i);
sub(N,i);
write(N);
return 0; }
[LE2] Am gasit o greseala , CodeBlocks, cand vede urmatorul cod si il ruleaza, nu ii modifica valoarea lui A :
A[i] += ( t = ( A[i] -= ( ( i <= B[0] ) ? B[i] : B[i] = 0 ) + t ) < 0 ) * 10; Dar daca inlocuiesc asa merge. De ce oare ? A[i] -= ( ( i <= B[0] ) ? B[i] : B[i] = 0 ), A[i] += ( t = ( A[i] + t ) < 0 ) * 10
Titlul: Răspuns: CodeBlocks
Scris de: Andrei Grigorean din Iunie 19, 2010, 19:58:06
Problema provine de la faptul ca tu presupui o anumita ordine de evaluare a expresiilor, lucru neprevazut de standard. Modul in care ai codat este groaznic, nu ar trebui sa folosesti niciodata asemenea instructiuni complicate. Scrie-le frumos, una cate una pe rand, si vei vedea ca iti va merge.
Deja m-am plictisit sa explic pe forum ca nu Code::Blocks e "de vina", ci compilatorul. E chiar asa greu sa intelegi?
Titlul: Răspuns: CodeBlocks
Scris de: Simoiu Robert din Iunie 20, 2010, 20:52:51
Dar am pus paranteze , deci ordinea ar trebui sa fie ok. Eu l-am rulat cu MinGW si pentru el ordinea e ok. Stiu ca CB nu e de vina, dar nu inteleg totusi ...
Titlul: Răspuns: CodeBlocks
Scris de: Codrea Marcel din Iunie 21, 2010, 08:46:12
MinGW si CodeBlocks sunt medii (IDE-uri) si fiecare contine cate un compilator, un editor de texte, un debugger s.a.m.d. Compilatoare sunt multe, fiecare firma software isi poate dezvolta propriul ei compilator, singura conditie fiind ca aceasta sa respecte standardul impus de limbaj.
Explicatia e simpla, compilatorul pe care il foloseste CodeBlocks nu a fost proiectat sa aiba comportamentul pe care il doresti pentru astfel de expresii "write-only" pentru ca probabil comportamentul pe care ti-l doresti nu e un standard al limbajului C++. Compilatorul lui MinGW implementeaza evaluarea expresiilor atat de complexe intr-un anumit mod, dar nu ca pe un standard al limbajului, ci ca pe un feature suplimentar.
Titlul: Răspuns: CodeBlocks
Scris de: Simoiu Robert din Iunie 21, 2010, 10:42:03
Multumesc, in sfarsit un raspuns complet. Si in legatura cu asta, nu se poate face nimic ?
Si inca ceva : pana acum mi-a mers perfect, nu stiu ce poate avea...
[LE] Am rezolvat, mi-am bagat compilerul de la MinGW si functioneaza :P. Multumesc pentru ajutor !
|