Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Ayak Eratosthenes: Mempercepatkan langkah "silang".

Ayak Eratosthenes: Mempercepatkan langkah "silang".

王林
王林ke hadapan
2024-02-09 12:36:09497semak imbas

Ayak Eratosthenes: Mempercepatkan langkah silang.

editor php Apple memperkenalkan kepada anda penapis Eratosthenes, algoritma untuk mengira nombor perdana dengan cepat. Algoritma ini menapis semua nombor perdana dengan terus mengecualikan gandaan nombor bukan perdana. Berbanding dengan kaedah tradisional untuk menilai nombor perdana satu demi satu, kaedah Ayak Eratosthenes boleh mempercepatkan proses pengiraan. Idea terasnya ialah merentasi dari 2 ke n, menandakan setiap gandaan nombor perdana p sebagai nombor bukan perdana sehingga lintasan selesai. Kaedah ini berfungsi dengan baik apabila mengira bilangan nombor perdana yang besar dan merupakan algoritma pengiraan nombor perdana yang cekap.

Kandungan soalan

Saya telah melaksanakan fungsi yang menyenaraikan nombor perdana menggunakan algoritma Ayak Eratosthenes seperti berikut:

func ListPrimes(n int) []int {
    primeList := make([]int, 0)
    primeBooleans := SieveOfEratosthenes(n)
    for p := 0; p < n+1; p++ {
        if primeBooleans[p] == true {
            primeList = append(primeList, p)
        }
    }
    return primeList
}

func SieveOfEratosthenes(n int) []bool {
    primeBooleans := make([]bool, n+1)
    sqrtN := math.Sqrt(float64(n))
    for k := 2; k <= n; k++ {
        primeBooleans[k] = true
    }
    for p := 2; float64(p) <= sqrtN; p++ {
        if primeBooleans[p] == true {
            primeBooleans = CrossOffMultiples(primeBooleans, p)
        }
    }
    return primeBooleans
}

func CrossOffMultiples(primeBooleans []bool, p int) []bool {
    n := len(primeBooleans) - 1
    for k := 2 * p; k <= n; k += p {
        primeBooleans[k] = false
    }
    return primeBooleans
}

Tetapi saya dapati ia tidak cekap: iaitu CrossOffMultiples 被调用的次数超出了必要的次数。 IOW,已经被“划掉”的整数将被划掉第二次或第三次(甚至更多次),因为任何多个 m 将有多个因素来划分它。但我似乎无法弄清楚如何利用这一点信息以允许我减少调用 CrossOffMultiples kali. Saya pasti ada cara untuk melakukan ini, tetapi atas sebab tertentu saya tidak boleh.

Ada cadangan?

Penyelesaian

Jika anda mengurangkan CrossOffMultiples 被调用的次数,即,您不对某些素数 p 调用它,则 p * p 不会被划掉。但你可以做的是从 p * p 而不是 2 * p mulakan kitaran.

Adalah perkara biasa untuk memotong nombor beberapa kali, inilah yang dilakukan oleh Sieve of Eratosthenes. Kaedah Ayak Linear ialah algoritma serupa yang mungkin menarik minat anda. p>

Atas ialah kandungan terperinci Ayak Eratosthenes: Mempercepatkan langkah "silang".. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam