2010-03-15 13 views
2

J'ai besoin d'aide pour réviser ceci. Il garde seulement l'affichage de 0 comme temp. Je vous remercie.C++ Nombre parfait. Besoin d'aide pour réviser

// A program to determine whether the input number is a perfect number 
// A perfect number is defined by the sum of all its positive divisors excluding itself 
// 28: 1+2+3+7+14 = 28. 

int perfect, limit, divisor; 

cout << "Please enter a positive integer in order to define whether it is a perfect integer or not: " ; 
cin >> perfect; 
cout << endl; 

int temp = 0; 
int prevtemp = 0; 
    limit = 1; 
    divisor = 1; 
while (limit < perfect) 
{ 

    if ((perfect % divisor) == 0) 
    { 
    divisor = prevtemp; 
    temp = prevtemp + temp; 
    } 

    limit++; 
    divisor++; 
} 

if (perfect == temp) 
    cout << "Your number is a perfect number!" << endl; 
else 
    cout << "Your number is not a perfect number" << endl; 

return 0; 

Répondre

1

Je ne suis pas sûr, mais je suppose que dans le code:

if ((perfect % divisor) == 0) 
    divisor = prevtemp; 

vous aviez l'intention d'être ce prevtemp=divisor à la place. Cela résout un problème évident, mais laisse toujours un peu qui ne semble pas faire ce que vous avez probablement prévu. Par exemple, je n'arrive pas à comprendre ce que limit est censé accomplir - vous l'initialisez et l'incrémentez, mais pour autant que je puisse voir, vous n'utilisez jamais sa valeur (eh bien, je suppose que vous l'utilisez, mais sa valeur est toujours la même que divisor, donc je ne sais pas pourquoi vous pensez avoir besoin des deux, ou comment limit a un sens comme son nom). Editer: Il serait logique d'avoir un limit. En particulier, les facteurs viennent toujours par paires: un facteur inférieur ou égal à la racine carrée du nombre, et un qui correspond au premier qui est toujours supérieur ou égal à la racine carrée du nombre. En tant que tel, vous n'avez pas besoin de scanner tout le chemin jusqu'au nombre lui-même à la recherche de facteurs - vous pouvez définir la racine carrée du nombre comme limite, et numériser seulement jusqu'à ce point. Pour chaque facteur que vous trouvez jusqu'à ce point, le facteur correspondant sera perfect/divisor. Puisque vous avez déjà obtenu un exemple de travail, je pense que je pourrais tout aussi bien espère que ce ne sont pas les devoirs, et après un exemple ainsi:

bool is_perfect(int number) { 
    int limit = sqrt((double)number); 
    int sum = 1; 

    for (int i=2; i<=limit; i++) 
     if (number % i == 0) 
      sum += i + number/i; 
    return sum == number; 
} 
+0

J'utilise la limite sur la boucle while afin que je puisse trouver tous les diviseurs qui ne laissent aucun reste jusqu'à parfait-1 – Sagistic

+0

Je l'ai eu, j'avais besoin de mettre le temp = prevtemp + temp; dans le bloc if ou bien, il va continuer à ajouter. J'ai modifié pour corriger cela. – Sagistic

+0

Haha, c'est les devoirs. Quel est le problème avec obtenir de l'aide? Encore une fois, merci pour votre aide, je l'apprécie. Je pensais utiliser le sqrt comme limite, je voulais juste un prototype fonctionnel en premier. – Sagistic

5

Vous définissez jamais prevtemp autre chose que 0, ce qui ajoute à temp ne fait rien.

Je crois que vous vouliez dire

if ((perfect % divisor) == 0) 
    temp += divisor; // not "divisor = prevtemp;" 

doit également être supprimée La ligne "temp = prevtemp + temp" avec cette solution; La variable prevtemp n'est plus nécessaire.

De même, il n'est pas nécessaire de conserver des variables limit et divisor distinctes, car elles sont toujours identiques. Supprimez simplement limit et modifiez la condition de boucle pour utiliser divisor. De plus, comme Mark Byers l'a souligné, la boucle serait plus simple à comprendre si vous l'avez refactorisée en une boucle for plutôt qu'en while.

+0

J'ai été battu. :) –

+0

Ah .. c'est ce que c'était, j'ai encore besoin de réparer un algorithme pour que cela fonctionne. Merci! – Sagistic

+0

Oui, même avec cette correction, il est dit 28 n'est pas parfait. –

0

Vous n'êtes jamais rien affecter à prevtemp après l'initialisation à 0, donc il n'y a rien à ajouter à temp sur la ligne qui lit temp = prevtemp + temp.

2

Il semble que vous faites trop compliqué. Voici comment vous pouvez le faire:

int total = 0; 
for (int i = 1; i < perfect; ++i) 
{ 
    if (perfect % i == 0) 
     total += i; 
} 

if (perfect == total) 
    cout << "Your number is a perfect number!" << endl; 
else 
    cout << "Your number is not a perfect number" << endl; 

Notez que le total en cours d'exécution est maintenue dans une variable appelée total (vous avez appelé cette température variable) et il est seulement augmenté lorsque le nombre est un diviseur exact.

+0

Merci. Cependant, je suis toujours confus sur les variables locales en utilisant des boucles for, donc je ne l'ai pas encore utilisé. – Sagistic

+0

Je vais apprendre vos moyens simples mais concis. – Sagistic

0
#include<iostream> 
#include<iomanip> 
using namespace std; 

int main(){ 
    int n,i=1,sum=0; 
    cout<<"Enter a number: "; 
    cin >> n; 
    while(i<n){ 
     if(n%i==0) 
      sum=sum+i; 
     i++; 
    } 
    if(sum==n) 
     cout << i << " is a perfect number"; 
    else 
     cout << i << " is not a perfect number"; 
    system("pause"); 
    return 0; 
} 
+0

Cette question a déjà une réponse acceptée. S'il y a quelque chose en particulier qui fait de votre réponse une amélioration, vous devriez fournir quelques explications. –