2009-10-11 22 views

risposta

13

No, ma è facile scrivere uno:

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

Dove vedi una possibile divisione per zero? sqrt (0) e cbrt (0) sono definiti. –

+0

La risposta originale che avevo in mente usava restituire 'n/root == root', ma alla fine ho usato un approccio diverso. Grazie per aver segnalato! Modifica la risposta. –

+3

Questo non sempre funziona, a causa di un errore in virgola mobile: se "sqrt()" o "cbrt()" accade per restituire epsilon meno della radice effettiva, il cast su un intero lo troncerà e il controllo verrà eseguito fallire. Per essere completamente a prova di proiettili, devi anche controllare se 'n == (root + 1) * (root + 1)' per il caso radice quadrata o se 'n == (root + 1) * (root + 1) * (root + 1) 'per il caso della radice del cubo. –

6

sqrt(x), o, in generale, pow(x, 1./2) o pow(x, 1./3)

Per esempio:

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: o in generale:

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

Il problema con l'utilizzo di 'pow (x, 1./3)' è che 1/3 non hanno una esatta rappresentazione in virgola mobile, in modo da non "veramente" ottenere la radice cubica. C99 in poi ha 'cbrt', che dovrebbe fare un lavoro migliore per ottenere la radice cubica. –

+0

Suppongo. Ma 'pow' si generalizza più facilmente, ed è abbastanza facile correggere errori in virgola mobile. –

1

Prova questa:

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

No, non ci sono funzioni standard C o C++ per verificare se un intero è un quadrato perfetto o un complemento perfetto cubo.

Se si vuole che sia veloce ed evitare di utilizzare il galleggiante/doppie routine di cui la maggior parte delle risposte, poi Codice una ricerca binaria utilizzando solo numeri interi. Se si riesce a trovare una n con n^2 < m < (n + 1)^2, allora m non è un quadrato perfetto. Se m è un quadrato perfetto, allora troverai un n con n^2 = m. Il problema è discusso here

0

Per identificare i quadrati provato questo algoritmo in Java. Con una piccola differenza di sintassi puoi farlo anche in C++. La logica è la differenza tra ogni due quadrati perfetti consecutivi continua ad aumentare per 2. Diff (1,4) = 3, Diff (4,9) = 5, Diff (9,16) = 7, Diff (16, 25) = 9 ..... continua. Possiamo usare questo fenomeno per identificare i quadrati perfetti. codice Java è,

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; 
} 

Per rendere l'identificazione delle piazze più velocemente possiamo usare un altro fenomeno, la somma ricorsiva di cifre del quadrati perfetti è sempre 1,4,7 o 9. Così un codice molto più veloce possibile Be ...

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

Per quadrato perfetto si può anche fare:

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

Per cubo perfetto è possibile:

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

Spero che questo aiuti.

+0

_IF_ questo era "about return", perché non solo 'return sqrt (n) == floor (sqrt (n))'? (e perché preferire 'floor' a' round'?) Quindi, c'è 'int r = round (cbrt (n)); return n == r * r * r' - nessuno dei quali è 'predefinito ', lasciando _non alla nostra conoscenza del 2016_: [risposta di Chris] (http://stackoverflow.com/a/1549960/3789665). – greybeard

0

Potremmo usare la funzione interna truc funzione -

#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)); 
} 
Problemi correlati