2009-10-11 8 views

Répondre

13

Non, mais il est facile d'écrire un:

bool is_perfect_square(int n) { 
    if (n < 0) 
     return false; 
    int root(round(sqrt(n))); 
    return n == root * root; 
} 

bool is_perfect_cube(int n) { 
    int root(round(cbrt(n))); 
    return n == root * root * root; 
} 
+0

Où voyez-vous une division possible par zéro? sqrt (0) et cbrt (0) sont définis. –

+0

La réponse originale que j'avais dans mon esprit utilisé renvoie 'n/root == root', mais j'ai fini par utiliser une approche différente. Merci d'avoir signalé! Éditera la réponse. –

+3

Cela ne fonctionne pas toujours, en raison d'une erreur de virgule flottante: si 'sqrt()' 'ou cbrt()' arrive à revenir epsilon inférieure à la racine réelle, la distribution à un nombre entier tronque que, et le chèque échouer. Pour être complètement pare-balles, vous devez également vérifier si 'n == (root + 1) * (root + 1)' pour la racine carrée ou si 'n == (root + 1) * (root + 1) * (racine + 1) 'pour le cas de la racine du cube. –

6

sqrt(x), ou en général, pow(x, 1./2) ou pow(x, 1./3)

Pour exemple:

int n = 9; 
int a = (int) sqrt((double) n); 
if(a * a == n || (a+1) * (a+1) == n) // in case of an off-by-one float error 
    cout << "It's a square!\n"; 

Edit: ou en général:

bool is_nth_power(int a, int n) { 
    if(n <= 0) 
    return false; 
    if(a < 0 && n % 2 == 0) 
    return false; 
    a = abs(a); 

    int b = pow(a, 1./n); 
    return pow((double) b, n) == a || pow((double) (b+1), n) == a; 
} 
+2

Le problème avec l'utilisation 'pow (x, 1./3)' est que 1/3 n'a pas une représentation exacte à virgule flottante, de sorte que vous ne sont pas "vraiment" en train d'obtenir la racine du cube. A partir de C99, 'cbrt' devrait faire l'objet d'un meilleur travail pour obtenir la racine du cube. –

+0

Je suppose. Mais 'pow' généralise plus facilement, et il est assez facile de corriger les erreurs en virgule flottante. –

1

Essayez ceci:

#include<math.h> 
int isperfect(long n) 
{ 
    double xp=sqrt((double)n); 
    if(n==(xp*xp)) 
     return 1; 
    else 
     return 0; 
} 
1

Non, il n'y a pas de norme c ou C++ fonctions pour vérifier si un entier est un carré parfait ou un parfait cube.

Si vous voulez que ce soit rapide et évitez d'utiliser les routines float/double mentionnées dans la plupart des réponses, codez une recherche binaire en utilisant uniquement des entiers. Si vous pouvez trouver un n avec n^2 < m < (n + 1)^2, alors m n'est pas un carré parfait. Si m est un carré parfait, alors vous trouverez un n avec n^2 = m. Le problème est discuté here

0

Pour l'identification des carrés j'ai essayé cet algorithme en java. Avec peu de différence de syntaxe, vous pouvez aussi le faire en C++. La logique est, la différence entre deux carrés parfaits consécutifs continue d'augmenter de 2. Diff (1,4) = 3, Diff (4,9) = 5, Diff (9,16) = 7, Diff (16, 25) = 9 ..... continue. Nous pouvons utiliser ce phénomène pour identifier les carrés parfaits. code Java est,

boolean isSquare(int num){ 
     int initdiff = 3; 
     int squarenum = 1; 
     boolean flag = false; 
     boolean square = false; 
     while(flag != true){ 

       if(squarenum == num){ 

        flag = true; 
        square = true; 

       }else{ 

        square = false; 
       } 
       if(squarenum > num){ 

        flag = true; 
       } 
      squarenum = squarenum + initdiff; 
      initdiff = initdiff + 2; 
    } 
       return square; 
} 

Pour rendre l'identification des carrés plus vite nous pouvons utiliser un autre phénomène, la somme récurrente de chiffres de carrés parfaits est toujours 1,4,7 ou 9. donc un code beaucoup plus rapide peut être ...

int recursiveSum(int num){ 
    int sum = 0; 
    while(num != 0){ 
    sum = sum + num%10; 
    num = num/10;   
    } 
    if(sum/10 != 0){   
     return recursiveSum(sum);  
    } 
    else{ 
     return sum; 
    } 

} 
    boolean isSquare(int num){ 
     int initdiff = 3; 
     int squarenum = 1; 
     boolean flag = false; 
     boolean square = false; 
     while(flag != true){ 

       if(squarenum == num){ 

        flag = true; 
        square = true; 

       }else{ 

        square = false; 
       } 
       if(squarenum > num){ 

        flag = true; 
       } 
      squarenum = squarenum + initdiff; 
      initdiff = initdiff + 2; 
    } 
       return square; 
} 

    boolean isCompleteSquare(int a){ 
    // System.out.println(recursiveSum(a)); 
    if(recursiveSum(a)==1 || recursiveSum(a)==4 || recursiveSum(a)==7 || recursiveSum(a)==9){ 

     if(isSquare(a)){ 

      return true; 

     }else{ 
      return false; 
     } 


    }else{ 

     return false; 


    } 

    } 
0

Pour carré parfait vous pouvez également faire:

if(sqrt(n)==floor(sqrt(n))) 
    return true; 
else 
    return false; 

Pour cube parfait, vous pouvez:

if(cbrt(n)==floor(cbrt(n))) 
    return true; 
else 
    return false; 

Espérons que cela aide.

+0

_IF_ c'était "à propos de return", pourquoi ne pas simplement "return sqrt (n) == floor (sqrt (n))"? (et pourquoi préférer 'floor' à' round'?) Ensuite, il y a 'int r = round (cbrt (n)); return n == r * r * r' - aucun n'est 'prédéfini', laissant _not à notre 2016 knowledge_: [la réponse de Chris] (http://stackoverflow.com/a/1549960/3789665). – greybeard

0

Nous pourrions utiliser la fonction truc builtin -

#include <math.h> 

// For perfect square 
bool is_perfect_sq(double n) { 
    double r = sqrt(n); 
    return !(r - trunc(r)); 
} 

// For perfect cube 
bool is_perfect_cube(double n) { 
    double r = cbrt(n); 
    return !(r - trunc(r)); 
} 
Questions connexes