Miért nem működik (megfelelően) ez a C++ program? (5) (forráskód lent)
Már majdnem befejeztem az euklideszi algoritmust elvégző programot (nyilván még van benne pár hiba), de nem tudom ellenőrizni, mert amint megadtam a 2 számot, a program kiakad. Egy programtervező informatikus ismerősöm azt mondta, hogy a végtelen ciklussal van a probléma. Ha valaki tudja, hogy mi(ke)t kellene átírni a forráskódban ahhoz, hogy megfelelően működjön, akkor az pls tegye meg.
Előre is köszi a válaszokat.
Itt a szósz kód:
#include <iostream>
using namespace std;
int n = 0 ; //Ezek itt a tömbök elemeinek "sorszámai".
int m = 0 ;
int p = 0 ;
int k = 0 ;
int RestMaker (int a, int b) // Ez a függvény képzi az
{ // osztási maradékokat.
int rest ;
rest = a%b ;
return (rest) ;
}
int QuotientMaker(int a, int b)// Ez a függvény a hányadosokat képzi.
{
int quotient ;
quotient = a/b ;
return (quotient) ;
}
// Ezek itt a tömbök.
int Number1Values [100] ; // Ez az osztandókat tárolja.
int Number2Values [100] ; // Ez az osztókat.
int Rests [100] ; // Ez a maradékokat.
int Quotients [100] ; // Ez pedig a hányadosokat.
int main()
{
int Number1 ; // A számpár első tagjának deklarációja.
int Number2 ; // A számpár második tagjának deklarációja.
int x ;
int Counter = 0 ;
cout << "This program will commit the Euclidean algorithm on " ;
cout << "the two positive intiger you enter. \n" ;
cout << "Enter the first number: " ;
cin >> Number1 ; // Az első szám beolvasása.
cout << "Enter the second number:" ;
cin >> Number2 ; // A második szám beolvasása.
if (Number1<Number2)
{
x = Number1;
Number1 = Number2;
Number2 = x;
}
int Number1a = Number1 ;
int Number2a = Number2 ;
int Number1b = Number1 ;
int Number2b = Number2 ;
for (;;) // Infinite loop.
{
Counter++ ;
Number1Values [p] = Number1 ; // Tároljuk az osztandót.
Number2Values [k] = Number2 ; // Tároljuk az osztót.
p++ ; // Inkrementáljuk a tömb indexét.
k++ ; // Inkrementáljuk a tömb indexét.
if (RestMaker(Number1a, Number2a) != 0) // Ha az osztás maradéka nem 0...
{
int rest ; // Maradék változó deklarálása.
rest = RestMaker(Number1a, Number2a) ;// Maradék változó kiszámítása.
// Egy üres sor :D
Rests [n] = rest ; // Eltároljuk az aktuális maradék értékét.
n++ ; // Ez elég triviális lépés.
Number1a = Number2a ;
Number2a = rest ;
}
if(RestMaker(Number1a, Number2a)== 0){
break ;
}
}
do
{
int Quotient ; // Ez a ciklus a hányadosokat számolja ki.
Quotient = QuotientMaker(Number1b, Number2b) ;
Quotients [m] = Quotient ;
m++ ;
Number1b = Number2b ;
Number2b = RestMaker (Number1b, Number2b) ;
}while (RestMaker(Number1b,Number2b) != 0 );
for (int count = 0; count <= Counter; count++)
{
int q = 0 ;
int w = 0 ;
int e = 0 ;
int r = 0 ;
cout << Number1Values[q] ;
cout << " = " ;
cout << Quotients[e] ;
cout << " * ";
cout << Number2Values[w] ;
cout << " + " ;
cout << Rests[r] ;
cout << "\n";
q++ ;
w++ ;
e++ ;
r++ ;
}
cout << Rests[Counter] ;
cout << " = " ;
cout << Number1Values[Counter] ;
cout << " - " ;
cout << Quotients[Counter] ;
cout << " * " ;
cout << Number2Values[Counter] ;
cout << " = " ;
cout << Rests[Counter-1] ;
cout << " - " ;
cout << Quotients[Counter] ;
cout << " * ( " ;
cout << Number1Values[Counter-1] ;
cout << " - " ;
cout << Quotients[Counter-1] ;
cout << " * " ;
cout << Number2Values[Counter-1] ;
cout << " ) " ;
for(int count2 = 0; count2 <= Counter; ++count2)
{
int q = 0 ;
int w = 0 ;
int e = 0 ;
int r = 0 ;
cout << " = " ;
cout << Quotients[Counter]*Quotients[Counter-count2]+1 ;
cout << " * " ;
cout << Number2Values[Counter-count2] ;
cout << " - " ;
cout << Quotients[Counter] ;
cout << " * ( " ;
cout << Number1Values[Counter-count2] ;
cout << " - " ;
cout << " = " ;
cout << Rests[Counter-count2] ;
cout << " - " ;
cout << Quotients[Counter] ;
cout << " * ( " ;
cout << Number1Values[Counter-count2] ;
cout << " - " ;
cout << Quotients[Counter-count2] ;
cout << " * " ;
cout << Number2Values[Counter-count2] ;
cout << " ) " ;
q++ ;
w++ ;
e++ ;
r++ ;
}
system ("PAUSE") ; //Hagyunk egy kis időt a felhasználónak a program
return 0 ; // bezárása előtt, hogy meg tudja nézni az eredményt.
}
Szerintem ezek a sorok a hibásak:
Number1b = Number2b ;
Number2b = RestMaker (Number1b, Number2b) ;
while(RestMaker(Number1b,Number2b) != 0);
A Number2b mindig 0, nullával meg nem osztunk, ez nálam "lebegőpontos kivétel"-t dobott.
"Miért nem működik (megfelelően) ez a C++ program?"
Túlbonyolítottad. Bocsi, de ez rettenetes programozási stílus,szúrja a szemem, ha kezdő vagy akkor nem, én is proginfós vagyok.
"Ha valaki tudja, hogy mi(ke)t kellene átírni a forráskódban ahhoz, hogy megfelelően működjön, akkor az pls tegye meg."
Egy általam átírt működő kód:
#include <iostream>
using namespace std;
void swap(int &a,int &b){ // 2 int értékének cseréje
int c=a;
a=b;
b=c;
}
void Euklidesz(int a,int b){// Euklideszi algoritmus rekurzív definíciója alapján iterációval
if (a<b)
swap(a,b);
while (b!=0){
cout << a << "=" << b << "*" << a/b << "+" << a%b << endl;
int a2,b2;
a2=b;
b2=a%b;
a=a2;
b=b2;
}
cout << "greatest common divisor:" << a << endl;
}
int main(){
cout << "This program will commit the Euclidean algorithm on " ;
cout << "the two positive intiger you enter. \n" ;
cout << "Enter the first number: " ;
cin >> Number1 ; // Az első szám beolvasása.
cout << "Enter the second number:" ;
cin >> Number2 ; // A második szám beolvasása.
Euklidesz(Number1,Number2);
system ("PAUSE") ; //Hagyunk egy kis időt a felhasználónak a program
return 0 ; // bezárása előtt, hogy meg tudja nézni az eredményt.
}
Bocsi így fordul:
#include <iostream>
using namespace std;
void swap(int &a,int &b){ // 2 int értékének cseréje
int c=a;
a=b;
b=c;
}
void Euklidesz(int a,int b){// Euklideszi algoritmus rekurzív definíciója alapján iterációval
if (a<b)
swap(a,b);
while (b!=0){
cout << a << "=" << b << "*" << a/b << "+" << a%b << endl;
int a2,b2;
a2=b;
b2=a%b;
a=a2;
b=b2;
}
cout << "greatest common divisor:" << a << endl;
}
int main(){
int Number1;
int Number2;
cout << "This program will commit the Euclidean algorithm on " ;
cout << "the two positive intiger you enter. \n" ;
cout << "Enter the first number: " ;
cin >> Number1 ; // Az első szám beolvasása.
cout << "Enter the second number:" ;
cin >> Number2 ; // A második szám beolvasása.
Euklidesz(Number1,Number2);
system ("PAUSE") ; //Hagyunk egy kis időt a felhasználónak a program
return 0 ; // bezárása előtt, hogy meg tudja nézni az eredményt.
}
Kedves utolsó Válaszoló!
Nagyon köszönöm, hogy átnézted a kódom, és írtál nekem egy újat, ami működik. Valóban kezdő programozó vagyok, és még nem tudok túl sok dolgot, és nem rendelkezek nagy tapasztalattal se, ezért lett ilyen a kódom. Viszont Én nem pont ilyenre terveztem a programot. Szeretném, ha a program felírná a legnagyobb közös osztót a 2 szám lineáris kombinációjaként. Valahogy így:
(360; 225)
360 = 1* 225 + 135
225 = 1* 135 + 90
135 = 1* 90 + 45
90 = 2* 45 + 0
45=135-90=135-(225-135)=2*135-225=2*(360-225)-225=2*360-225
Láttam pár jó "trükköt" a kódban, amit írtál, tanultam belőle. Nem várom el, hogy írd meg azt, amit én gondoltam, de az nagyon jó lenne, ha adnál pár tanácsot, hogy hogyan kellene felépíteni.
Köszönöm szépen a segítséget ;)
Most elnézegettem a kódot, és tényleg zseniálisan van megírva. Kb. 100 sorral rövidebb és jól átlátható.
Te mióta tanulod a C++-t?
Nekem is van két verzióm, nem telt semmibe bemásolni:
#include <iostream>
using namespace std;
int gcd(int a, int b)
{
while(a != b)
{
if(a > b) a-=b; //a=a-b;
else b-=a;
}
return a;
}
int gcd_2(int a, int b)
{
int t;
while(b != 0)
{
t=b;
b=a%b;
a=t;
}
}
int main()
{
int a,b;
cout<<"Első szám: ";
cin>>a;
cout<<"Második szám: ";
cin>>b;
cout<<"Legnagyobb közös osztójuk: "<<gcd(a,b)<<endl;
}
"Szeretném, ha a program felírná a legnagyobb közös osztót a 2 szám lineáris kombinációjaként."
" ...jó lenne, ha adnál pár tanácsot, hogy hogyan kellene felépíteni. ..."
Nem pont kezdőknek való nyelv a c++ és ez nem pont kezdőknek való feladat, de leírom.
Úgy kell módosítani az euklideszi algoritmust hogy a lépéseket ne kiírja hanem eltárolja egy dinamikus adatszerkezetbe (pl. egy hasítótáblába). A tárolt lépésekből fel kell építeni a lineáris 2 szám lineáris kombinációjához vezető utat, ehhez egy fát kell bejárni.
Próbálgasd papíron fákkal ábrázolni, bejárni.
Számított fát ajánlok, memorizálással. A zárójeles kifejezéseket tárolni kell valamilyen módon (valamilyen belső adatszerkezetbe) Ezeket osztályokba érdemes becsomagolni. Használj segéd osztályokat ha kell. Továbbá ajánlott használni az STL-t.
"Te mióta tanulod a C++-t?"
2 éve.
Egyetemista vagy? Középsulis?
Köszi szépen a segítséget.
Még középiskolába járok, csak érdekel a programozás.
Nagyon szívesen.
Ha jól tudom ez középiskolába az euklideszi algoritmus nem tananyag. Pedig szerintem egyszerűbb megérteni mint a prímtényezőkre bontogatást, de ez csak egy szubjektív vélemény.
Az viszont tény hogy gyakorlatba ezt használják.(pl. matematikai szoftverekbe) Mert ugye nagyon a nagy számok (200 300 jegyű számra kell gondolni) felbontása exponenciális idejű. Egy jól megválasztott 300 jegyű számot jelenlegi tudásunk szerint nem tudnák felbontani a naprendszer élettartama alatt sem. Ugyanakkor bármely 2 300 jegyű szám legnagyobb közös osztóját euklideszi algoritmussal egy olcsó gép is el tudja végezni egy csettintés alatt.
20:41
int gcd(int a, int b) Ez a változat nagy számra exponenciális idejű lehet. Példának jó, de egyébként nem szép dolog a maradékot kivonogatásokkal megállapítani.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!