2009-10-11 9 views

Odpowiedz

13

No, ale łatwo jest napisać jeden:

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

Gdzie widzisz możliwy podział przez zero? sqrt (0) i cbrt (0) są zdefiniowane. –

+0

Oryginalna odpowiedź, którą miałem w głowie użyłem return 'n/root == root', ale skończyło się na zastosowaniu innego podejścia. Dzięki za wskazanie! Odpisze odpowiedź. –

+3

To nie zawsze działa, z powodu błędu zmiennoprzecinkowego: jeśli 'sqrt()' lub 'cbrt()' zwróci epsilon mniej niż rzeczywisty root, rzutowanie na liczbę całkowitą spowoduje obcięcie tego, a sprawdzanie zawieść. Aby być całkowicie odpornym na kule, musisz również sprawdzić, czy 'n == (root + 1) * (root + 1)' dla pierwiastka kwadratowego lub jeśli 'n == (root + 1) * (root + 1) * (root + 1) 'dla przypadku głównego kostki. –

6

sqrt(x), albo w ogóle, pow(x, 1./2) lub pow(x, 1./3)

Dla Przykład:

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: albo ogólnie:

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

Problem (x, 1./3)' jest to, że 1/3 nie posiada dokładną reprezentację w zmiennoprzecinkowych, więc "nie jest" naprawdę "uzyskiwanie pierwiastka kostki. Od C99 ma 'cbrt', który powinien wykonać lepszą robotę, aby uzyskać rdzeń kostki. –

+0

Przypuszczam. Ale 'pow' uogólnia się łatwiej i łatwo jest poprawić błędy zmiennoprzecinkowe. –

1

Spróbuj tego:

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

Nie istnieją żadne standardowe funkcje C lub C++, aby sprawdzić, czy dana liczba całkowita jest idealny kwadrat lub idealnym sześcian.

Jeśli chcesz, aby był szybki i unikaj używania funkcji float/double wymienionych w większości odpowiedzi, zakoduj wyszukiwanie binarne, używając tylko liczb całkowitych. Jeśli możesz znaleźć n z n^2 < m < (n + 1)^2, to m nie jest idealnym kwadratem. Jeśli m jest idealnym kwadratem, to znajdziesz n z n^2 = m. Problem jest dyskutowany here

0

Do identyfikacji kwadratów wypróbowałem ten algorytm w Javie. Przy niewielkiej różnicy składni można to zrobić również w języku C++. Logika polega na tym, że różnica między co dwoma kolejnymi idealnymi kwadratami wzrasta o 2. Diff (1,4) = 3, Diff (4,9) = 5, Diff (9,16) = 7, Diff (16, 25) = 9 ..... trwa. Możemy wykorzystać to zjawisko do identyfikacji idealnych kwadratów. kod Java jest

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

Aby dokonać identyfikacji kwadratów szybciej możemy użyć innego zjawiska, rekurencyjne suma cyfr idealnych kwadratów jest zawsze 1,4,7 lub 9. więc znacznie szybciej kod może być ...

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

Dla idealnego kwadratu można również zrobić:

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

Dla idealnego sześcianu można:

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

Mam nadzieję, że to pomoże.

+0

_IF_ to było "o powrocie", dlaczego nie po prostu 'return sqrt (n) == floor (sqrt (n))'? (i dlaczego wolisz 'floor' na' round'?) Następnie jest 'int r = round (cbrt (n)); return n == r * r * r' - żadna z nich nie jest "predefiniowana", pozostawiając _nie do naszej wiedzy 2016: [Chris 'odpowiedź] (http://stackoverflow.com/a/1549960/3789665). – greybeard

0

Mogliśmy użyć wbudowanego truc funkcję - z użyciem `pow

#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)); 
} 
Powiązane problemy