Поиск идеальных чисел от 1 до 100 - PullRequest
0 голосов
/ 12 октября 2009

Как мне сгенерировать все идеальные числа от 1 до 100?

Совершенное число - это положительное целое число, равное сумме его собственных делителей. Например, 6 (= 1 + 2 + 3) - идеальное число.

Ответы [ 3 ]

3 голосов
/ 13 октября 2009

Так что я подозреваю, что Фрэнк ищет ответ в Прологе, и да, он действительно пахнет домашнее задание ...

Ради интереса я решил написать свой ответ. Это заняло у меня около 50 строк.

Итак, вот схема того, как выглядят мои предикаты. Может быть, это поможет вам думать о прологе.

  is_divisor(+Num,+Factor)

  divisors(+Num,-Factors)
  divisors(+Num,+N,-Factors)

  sum(+List,-Total)
  sum(+List,+Sofar,-Total)

  is_perfect(+N)

  perfect(+N,-List)

+ и - на самом деле не являются частью имен параметров. Это документальная подсказка о том, что автор ожидает создания экземпляра. (NB) «+ Foo» означает, что вы ожидаете, что Foo будет иметь значение при вызове предиката. «-Foo» означает, что вы ожидаете, что Foo будет переменной при вызове предиката, и дадите ему значение к моменту окончания. (вроде как ввод и вывод, если это помогает так думать)

Всякий раз, когда вы видите пару предикатов, таких как sum / 2 и sum / 3, шансы равны сумме / 2, которая похожа на оболочку для суммы / 3, которая делает что-то вроде аккумулятора .

Я не удосужился заставить его распечатывать их красиво. Вы можете просто запросить его непосредственно в командной строке Prolog:

?- perfect(100,L).
L = [28, 6] ;
fail.

Еще одна вещь, которая может оказаться полезной, которую я нахожу с предикатами Пролога, это то, что обычно есть два вида. Один - это тот, который просто проверяет, правда ли что-то. Для такого рода предикатов вы хотите, чтобы все остальное не сработало. Они не должны быть рекурсивными.

Другие захотят просмотреть диапазон (чисел или списка) и всегда возвращать результат, даже если он равен 0 или []. Для этих типов предикатов вам нужно использовать рекурсию и подумать о своем базовом случае.

НТН.

Примечание: это называется «режим», и вы можете указать их, и компилятор / интерпретатор будет применять их, но я лично использую их в документации. Также пытался найти страницу с информацией о режиме Пролог, но я не могу найти хорошую ссылку. (

1 голос
/ 12 октября 2009

Похоже, вам нужно зацикливаться, пока n / 2 не станет 1/2 от n. Разделите число, и если остатка нет, вы можете включить его в итоговое значение. После того, как вы исчерпали 1/2 от n, вы проверяете, добавил ли ваш итог = число, которое вы тестируете.

Например:

#include "stdafx.h"
#include "iostream"
#include "math.h"
using namespace std;

int main(void)
{
    int total=0;

    for(int i = 1; i<=100; i++)
    {
        for( int j=1; j<=i/2; j++)
        {
            if (!(i%j))
            {
                total+=j;
            }
        }
        if (i==total)
        {
            cout << i << " is perfect";
        }
        //it works
        total=0;
    }

    return 0;
}
1 голос
/ 12 октября 2009

Я не уверен, что это то, что вы искали, но вы всегда можете просто распечатать "6, 28" ...

...