Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Java: Alkulukujen hakeminen

Sami [21.10.2004 15:53:46]

#

Ohjelma hakee n ensimmäistä alkulukua.

Edetessään ohjelma käyttää hyödyksi jo aiemmin löydettyjä lukuja, eli se yrittää jakaa tutkittavaa lukua vain niillä alkuluvuilla, jotka ovat pienempiä tai yhtäsuuria, kuin tutkittava luku.

Lopuksi ohjelma kirjoittaa löydetyt alkuluvut tiedostoon alkuluvut.txt.

Joitakin laskenta-aikoja:
100000 ensimmäistä alkulukua: < 1s
1000000 ensimmäistä alkulukua: ~ 12s
5000000 ensimmäistä alkulukua: ~ 2min

import java.io.*;

public class Alkuluku {
	public static void main(String[] args) {
		int n = 100000; // Montako ensimmäistä alkulukua haetaan
		int loydetty = 0; //löytyneiden alkulukujen lukumäärä
		int[] alkuluvut = new int[n]; //Taulukko, jonne kasataan löydetyt alkuluvut
		alkuluvut[0] = 1; // Vaatii toimiakseen parin ensimmäisen luvun asettamisen alkuarvoiksi
		alkuluvut[1] = 2; // (muuten tulee nollalla jakaminen tai ikuinen silmukka)


		int tutkittava = 1; // Luku, jota tutkitaan
		while(loydetty < n) {
			boolean olikoalkuluku = true;

			// Yritetään jakaa lukua vain niillä alkuluvuilla, jotka ovat pienempiä tai yhtäsuuria, kuin
			// tutkittavan luvun neliöjuuri.
			int raja = (int)(Math.sqrt(tutkittava));
			for (int i = 1; alkuluvut[i] <= raja; i++) {
				// Jos tutkittavan luvun ja jonkin sen neliöjuurta edeltävän alkuluvun jakojäännös
				// on nolla, niin luku ei ole alkuluku
				if ((tutkittava % alkuluvut[i]) == 0) {
					olikoalkuluku = false;
					break;
				}
			}

			// Jos luku oli alkuluku, niin lisätään se alkulukutaulukkoon
			if (olikoalkuluku) {
				alkuluvut[loydetty] = tutkittava;
				loydetty++;
			}
			tutkittava++;
		}

		// Lopuksi kirjoitetaan n ensimmäistä alkulukua tiedostoon alkuluvut.txt
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter("alkuluvut.txt"));
			for (int i = 0; i < n; i++) {
				out.write(alkuluvut[i] + ", ");
			}
			out.close();
		} catch (IOException e) {
			System.out.println("Virhe tiedostoon kirjoitettaessa!");
		}
	}
}

Sami [21.10.2004 16:03:27]

#

typokorjaus kuvaukseen:
"jotka ovat pienempiä tai yhtäsuuria, kuin tutkittava luku." pitäisi olla "jotka ovat pienempiä tai yhtä suuria, kuin tutkittavan luvun neliöjuuri."

Blaze [21.10.2004 20:57:49]

#

Vinkkiä VOI muokata, ettei tarvitse kommentteihin niitä korjauksia laittaa.

Minulla on tällainen laskimelle (TI-86) ^_^
Vois siihenkin tehä tuon lukujen cacheamisen. Nopeutuis kummasti.

tejeez [22.10.2004 22:35:56]

#

Tää ei kyl oo mikään kovin hyvä tapa hakea alkulukuja :)

msdos464 [22.10.2004 23:01:11]

#

            int raja = (int)(Math.sqrt(tutkittava));
            for (int i = 1; alkuluvut[i] <= raja; i++) {
                // Jos tutkittavan luvun ja jonkin sen neliöjuurta edeltävän alkuluvun jakojäännös
                // on nolla, niin luku ei ole alkuluku
                if ((tutkittava % alkuluvut[i]) == 0) {
                    olikoalkuluku = false;
                    break;
                }

olis varmaan nopeempi näin:

            for (int i = 1; alkuluvut[i] * alkuluvut[i]<= tutkittava && olikoalkuluku; i++) {
                olikoalkuluku = ((tutkittava % alkuluvut[i]) == 0);
                }

ja sitten:

tutkittava++;

=>

int tutkittava = 3; // siis tonne alkuun

tutkittava += 2;

ja pistetään taulukkoon indeksiin 0 luku 2.

======
edit: 1 ei ole alkuluku.

Mkz [21.10.2005 18:03:28]

#

Oon itekki tehny tällasen javalle. Tosin se on vain 200x hitaampi, mutta sen tarkoitus onkin antaa vain yksi alkuluku. (Mun koodi on kyl puolet lyhempiki)

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta