» »

[C++] Optimizacija funkcije za izračun prafaktorjev

[C++] Optimizacija funkcije za izračun prafaktorjev

Deno ::

Funkcija nam razstavi podano naravno število na prafaktorje. Ker pa to traja kar nekaj časa, me zanima, kako bi se dalo stvar nekako optimizirati za hitrejše delovanje (pri velikih številkah). En način bi bil, da bi že predhodno vpisal praštevila in jih ne bi iskal v programu, ampak to me omeji na določeno število praštevil. Zato program sam poišče praštevila. Koda je sledeča:

int Razstavi (int stevilo)
{
	int st_del, pfaktor, p_stevilo;
	int del = 0;
	bool pra;

	
	for (int i = 1; i <= stevilo; i++) //Glavna zanka
	{
		
		p_stevilo = stevilo; // pomozno stevilo, katerega bomo delili (s tem se podano stevilo ne spremeni)
		st_del = 0; // St. deliteljev je na zacetku 0
		pra = false; // Predpostavimo, da trenutni i ni prastevilo

		for (int y = 1; y <=i; y++) // Preverimo, ce je stevilo i v zanki prastevilo
		{
			if ((i % y) == 0) st_del++; // Ce je ostanek 0, je y deljitelj stevila i
		}
		if (st_del == 2) pra = true; // Ce ima i dva delitelja (1 in samega sebe), je i prastevilo

		
		if (pra) // Ce je i prastevilo, nadaljujemo z deljenjem
		{
			if (stevilo % i == 0) // Ce je i deljivo s stevilom, je njegov prafaktor
			{
				pfaktor = i;
				cout << "Prafaktor stevila " << stevilo << " je " << i << endl;
				

				while (p_stevilo >= i) // Preverimo, ce je i veckratni prafaktor stevila
				{
					p_stevilo = p_stevilo / i;
					if (p_stevilo % i == 0) // Ce i == veckratni prafaktor ga izpisemo
					cout << "Prafaktor stevila " << stevilo << " je " << i << endl;
					 else 
					break; // Ce i ni veckratni prafaktor, prekinemo zanko in se vrnemo
				
				}
			}
		}
	} // Konec glavne zanke

	cout << "Prafaktor stevila " << stevilo << " je 1" << endl;; // Na koncu dodamo se 1

	cout << endl;
	cout << endl;
	
	return 0;
}
  • spremenil: Deno ()

OwcA ::

Načeloma lahko iščeš delitelje danega števila samo do njega korena zaokroženo navzdol. Naprej se zgodba ponavlja.

Če ni deljivo z dva ne bo tudi z nobenim večjim sodim številom. Zato pregleduj le liha.

Deljivost s sodim številom hitreje ugotviš manipulacijo bitov.

Tako za začetek.
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

Thomas ::

Najprej bi se blo treba zment.

Hočemo imet število deljiteljev ali vse deljitelje?

:\

Gundolf ::

Prvic: splaca si zapomniti vsako prastevilo ki ga najdes (naredis tabelico)
Drugic: ko isces nova prastevila si pomagas z ze najdenimi (iz prejsnje tabelice) in delis le z njimi.
Tretjic: kot je ze owca reku ne pregledujes za delitelje vseh stevil ampak le stevila do kvadratnega korena danega stevila. Ko najdes delitelja, si v bistvu nasel dva: delitelj in stevilo / delitelj.

Tole je za zacetek, verjetno bi se se kaj naslo. Ce ti to uspe implamentirati bos mocno skrajsal vse zanke in s tem seveda izvajalni cas programa.

Gundolf ::

Aja se to. Morda se ne slisi veliko, ampak optimizacije se lahko zacnejo s tem, da upostevas nesmiselnost deljenja z 1 in s samim sabo (v tisti zanki for (int y = 1....)).

Thomas ::

Jest na tole gledam mau drgač.

Bistvena razlika je, če iščemo število deljiteljev ali če iščemo kateri deljitelji to so.

Če gledamo neko random število do N, ali če gledamo za vsa števila do N.

Bom pokazal na primeru 100.

Najprej preizkusimo deljivost z vsemi praštevili do Sqrt(100). To je z 2, 3, 5, 7.

Potem preizkusimo z vsemi kvadrati praštevil, ki so se doslej izkazali kot deljitelji. 2*2 in 5*5. Potem še s permutacijami 2*5 ... Pri tem ....

U glavnem zdej nimam časa invokat še Critticall.

Gundolf ::

Se strinjam s thomasom, nujno rabimo vec podatkov o tem kaj sploh delas deno! :)

Drugace pa namsto da preizkusas prastevila, nato njihove kvadrate in permutacije lahko enostavno vsakic ko najdes delitelja svoje stevilo delis z njim in isces ostale na novem stevilu. Pri tem pa ne smes pozabiti da istega delitelja poskusis se enkrat. Dobis eno samo kratko zanko, le se prastevila si moras prej poiskati.

SasoS ::

Dobis eno samo kratko zanko, le se prastevila si moras prej poiskati.

Dejansko ti praštevil ni treba poiskati prej. Ker...namanjši deljitel števila bo vedno praštevilo ;). Aja, pa 1 ni praštevilo.

Thomas ::

Sej zato! Če iščeš za eno samo število, praštevila poiščeš sproti. Če pa za več, se jih splača zračunati vnaprej.

Sicer se dokaj strinjam se predgovornikoma.

Thomas ::

Na, tle je programcic v Critticall Cju, ki ti napiše števila do 100 in njihove deljitelje v tabelo.


$dimensions tabela[600]
$declareint i j index tmp
$retvar tabela[]
$showvar index
for (i=0;i<100;i++) {
    tabela[index]=i;index++;
    for (j=1;j<=i;j++) {
        tmp=i%j;
        if (tmp==0) {tabela[index]=j;index++;}
    } 
}



Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

NUJNO!Algoritmi C++

Oddelek: Pomoč in nasveti
211964 (1226) DOOM_er
»

Logični podatkovni tip

Oddelek: Programiranje
91657 (1392) Spura
»

Pomoc programiranje - Napisite funkcije

Oddelek: Programiranje
102030 (1619) FuI2cY
»

[Java] Prafaktorji

Oddelek: Programiranje
61634 (1487) darkkk
»

kako definirtati prastevilo

Oddelek: Programiranje
143784 (3589) ooux

Več podobnih tem