簡體   English   中英

C素數分解(循環失敗?)

[英]C prime factorization (loop failure?)

我一直在研究這段簡單的代碼1.5個小時,但沒有發現錯誤。 我開始瘋了;)

你們每個人只要有新的想法和觀點,都可以給我一點提示,我可能在哪里出現錯誤? (我是C的新手)

問題是:該代碼對於我輸入並測試的大多數數字都可以正常工作,但是偶然地我發現了一個不起作用的數字:3486118(或55777888的整數倍),它適合於第一個循環,但是在因子2之后,它將變成一個無限循環。

這是我的代碼:(非常感謝您的幫助)

// Program calculates prime factors of entered number and returns them

#include <stdio.h>

int main() {

    long int num, num_cp;
    long int product=1;

    /*prime number array up to 100.000*/
    long int prime[] = {2, 3, **[...cut out MANY numbers...]** 99971, 99989, 99991};

    printf("Please enter a positive integer:\n");
    scanf("%li", &num);//55777888 or 3486118 not working... why?
    //copy the entered number to keep the original for comparison with "product" and "break;" if equal
    num_cp=num;

    printf("prime factorization of %li:\n\n", num);

    for (int i=0; i<sizeof(prime); i++) {
        if (num_cp%prime[i]==0) {
            num_cp/=prime[i];
            product*=prime[i];
            if (product==num) {
                printf("%li\n\n", prime[i]);
                break;
            }
            printf("%li*", prime[i]);

            //If prime factor found but "product" is still not equal to "num" reset loop counter "i" to -1 (==0 in next loop)
            i=-1;
        }
    }
    printf("END");
    return 0;
}

“我一直在研究這段簡單的代碼1.5個小時,但沒有發現錯誤。我開始發瘋了;)”

別。 別管它。 走開,吃披薩。 在您最喜歡的電影前播放視頻。 洗個澡。 力爭在2048(或更高水平)上取得新的高分。 您的大腦陷入了車轍,您再也看不到代碼了。 您只會看到您認為的代碼。

當您精疲力盡時,然后-僅在此之后-返回並實際閱讀您編寫的代碼。 不是您認為自己編寫的代碼,而是您實際編寫的代碼。 是的,它們是不同的。

55777888的主要因子是2·2·2·2·2·1743059,其中最后一個因子太大而無法包含在列表中。

您可以在代碼中解決此問題:當乘積等於找到的素數乘積時, num_cp為1。如果在用完素數列表后num_cp大於1,則為num 如果num/num_cp小於您檢查的最大素數,則可以假定num_cp的剩余值為素數。 如果不是,那么您會更早發現更多因素。

您可以通過在主循環后添加其他檢查來解決此問題:

if (num_cp > 1) printf("%li\n\n", num_cp);

(如果long int是系統上的64位數字,則您仍然不安全:剩余因素可能由數組中沒有的幾個數字組成。)

最后:重置for循環計數器以使循環重新開始不是一個好主意。 它總是從頭開始,並重新檢查您已經檢查過的素數。 而且這不是自然的程序流程,這使得它很難閱讀。 我認為,使用while循環而不是內部if塊會更自然。

編輯 :以說明:

#include <stdio.h>

int main() {
    long int num;

    /* prime number array up to 100.000 */
    long int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
    int nprime = sizeof(prime) / sizeof(*prime);

    num = 55;

    printf("%li == ", num);

    for (int i = 0; i < nprime; i++) {
        long int p = prime[i];

        if (num <= 1) break;

        while (num % p == 0) {
            num /= prime[i];
            printf("%li", p);
            if (num > 1) printf(" * ");
        }
    }

    if (num > 1) printf("%li", num);
    printf("\n");

    return 0;
}

注意事項:

  • 不用重置主循環計數器i ,而是使用while循環,它消耗了相同因子的所有重復。 如果素數p不除數,則不輸入while循環,就像if子句一樣。
  • 我刪除了num的副本並在整個過程中使用了num ,主要是為了消除混亂。 我還刪除了該product 所有素因應乘以原始數的邏輯是好的。 但這也反過來起作用:將數字除以所有質數后,剩下的就是1。無論如何,我們必須對數字進行除法。 通過刪除產品,我們必須僅跟蹤一個變量,而不是兩個變量。
  • 我已將break條件移到最前面,因此我們早早發現了負數和0。

也就是說,您的編碼方式沒有錯,在某些地方也許有點不尋常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM