簡體   English   中英

如何從 C 中的用戶給定數字打印 10 個完美數字?

[英]How to print 10 perfect numbers from a user given number in C?

我不知道如何打印接下來的十個完美數字 這是我到目前為止所得到的:

#include <stdio.h>

int main() {
    int n, c = 1, d = 2, sum = 1;
    printf("Enter any number \n");
    scanf("%d", &n);
    printf("The perfect numbers are:");
    while(c <= 10) { 
        sum = 1;
        d = 2;
        while(d <= n / 2) { //perfect no
            if(n % d == 0) {
                sum = sum + d;
            }
            d++;
        }
        if(sum == n) {
            printf("%d\n", n);
        }
        c++;
    }
    return 0;
}

我目前收到的 output:

input: 2 (say)  
output: 6  

我想要的是:

input: 2  
output:
6  
28  
496  
8128  
33550336  
858986905  
137438691328  
2305843008139952128  
2658455991569831744654692615953842176
191561942608236107294793378084303638130997321548169216

我剛剛開始編碼。 任何幫助將不勝感激。

幾個人提到的 integer 溢出問題很重要,但次要 即使我們修復了您損壞的邏輯,並對其進行調整以處理更大、固定大小的整數:

#include <stdio.h>

int main() {
    unsigned long long number;
    printf("Enter any number \n");
    scanf("%llu", &number);
    printf("The perfect numbers are:\n");

    int total = 0;

    while (total < 10) { 
        unsigned long long sum = 1, divisor = 2;

        while (divisor <= number / 2) {
            if (number % divisor == 0) {
                sum += divisor;
            }
            divisor++;
        }

        if (sum == number) {
            printf("%llu\n", number);
            total++;
        }

        number += 1;
    }

    return 0;
}

您仍然無法在任何合理的時間內超過前四個完美數字:

> ./a.out
Enter any number 
2
The perfect numbers are:
6
28
496
8128

主要問題是您使用了錯誤的算法 閱讀梅森素數及其與完美數的關系,以及盧卡斯-萊默檢驗 這種方法需要更多的思考,但令人驚訝的是,沒有更多的代碼。 並且會更快地產生更多結果(盡管最終也會陷入困境。)

找到完美數后必須放置計數器,因此在檢查完美數的if語句中必須增加c ,如下所示:

if(sum==n){
    printf("%d",n);
    c++;
}

在此之后,您需要增加稱為 n 的數字,如下所示:

n++;

根據數字,@Jonathan Leffler 是對的,您應該使用適當的變量。

從 output 你寫我相信你想顯示 10 個第一個完美數字現在你只顯示 6 因為你顯示它們從 1 到 10。在這個范圍內只有 6。我這樣寫:

#include <stdio.h>
int isperfect(int input) {
int sum = 0, value = input / 2;
do {
    if (input % value == 0) sum += value;
    value--;
} while (value);
if (input == sum) return 1;
else return 0;
}
int main() {
int i;
int count;
for (i = 2, count = 0; count < 4; i++) {
    if (isperfect(i) == 1) {
        count++;
        printf("%d\n", i);
    }
}
return 0;
}

但我不建議數超過 4,因為它會花費太多時間

研究,分而治之

完美數的形式為 2 p - 1 * (2 p - 1)。

代碼需要擴展精度才能形成191561942608236107294793378084303638130997321548169216

提高效率

迭代到<= n / 2需要很長時間。 迭代到<= n / d

// while(d <= n / 2) {
while(d <= n / d) {

示例改進代碼:

bool isprime(unsigned long long x) {
  if (x > 3) {
    if (x % 2 == 0) {
      return false;
    }
    for (unsigned long t = 3; t <= x / t; t += 2) {
      if (x % t == 0) {
        return false;
      }
    }
    return true;
  }
  return x >= 2;
}

高級:有關梅森數的快速素數檢驗,請參見Lucas-Lehmer 素數檢驗


下面的代碼適用於除第 10 個完美數字之外的所有數字,因為代碼必須測試 isprime(2 67 - 1) 並且我應該為 OP 留下一些事情要做。

static void buff_mul(char *buff, unsigned power_of_2) {
  unsigned long long m = 1ull << power_of_2;
  size_t len = strlen(buff);
  unsigned long long carry = 0;
  for (size_t i = len; i > 0;) {
    i--;
    unsigned long long sum = (buff[i] - '0') * m + carry;
    buff[i] = sum % 10 + '0';
    carry = sum / 10;
  }
  while (carry) {
    memmove(buff + 1, buff, ++len);
    buff[0] = carry % 10 + '0';
    carry /= 10;
  }
}

void print_perfext(unsigned p) {
  // 2**(p-1) * (2**p - 1)
  assert(p > 1 && p <= 164);
  char buff[200] = "1";
  buff_mul(buff, p);
  buff[strlen(buff) - 1]--; // Decrement, take advantage that the LSDigit is never 0
  buff_mul(buff, p - 1);
  puts(buff);
  fflush(stdout);
}

//unsigned next_prime(unsigned first_numeber_to_test_if_prime) {
#include <stdio.h>

int main() {
  unsigned p = 0;
  for (unsigned i = 0; i < 9; i++) {
   // If p prime && 2**p − 1 is prime, then 2**(p − 1) * (2**p − 1) is a perfect number.
    while (!isprime(p) || !isprime((1uLL << p) - 1))
      p++;
    printf("%2u ", p);
    print_perfext(p);
    p++;
  }
  return 0;
}

Output

 2 6
 3 28
 5 496
 7 8128
13 33550336
17 8589869056
19 137438691328
31 2305843008139952128
61 2658455991569831744654692615953842176

暫無
暫無

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

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