2009-10-11 44 views

Trả lời

13

Không, nhưng rất dễ dàng để viết một:

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

Bạn thấy một phân chia có thể bằng 0 ở đâu? sqrt (0) và cbrt (0) được xác định. –

+0

Câu trả lời ban đầu mà tôi có trong đầu mình đã sử dụng trả về 'n/root == root', nhưng tôi đã sử dụng một cách tiếp cận khác. Cảm ơn bạn đã chỉ ra! Sẽ chỉnh sửa câu trả lời. –

+3

Điều này sẽ không phải lúc nào cũng hoạt động, do lỗi dấu phẩy động: nếu 'sqrt()' hoặc 'cbrt()' xảy ra để trả về epsilon nhỏ hơn gốc thực, phép đúc thành một số nguyên sẽ cắt ngắn và kiểm tra sẽ Thất bại. Để được chống đạn hoàn toàn, bạn cũng cần phải kiểm tra nếu 'n == (root + 1) * (root + 1)' cho trường hợp căn bậc hai hoặc nếu 'n == (root + 1) * (root) + 1) * (root + 1) 'cho trường hợp gốc khối lập phương. –

6

sqrt(x), hoặc nói chung, pow(x, 1./2) hoặc pow(x, 1./3)

Đối Ví dụ:

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: hay nói chung:

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

Vấn đề với sử dụng 'pow (x, 1./3)' là 1/3 không có một đại diện chính xác trong dấu chấm động, vì vậy bạn "không" thực sự "nhận được khối lập phương. C99 trở đi có 'cbrt', nên thực hiện tốt hơn việc lấy gốc khối. –

+0

Tôi cho là vậy. Nhưng 'pow' tổng quát dễ dàng hơn, và nó đủ dễ dàng để sửa lỗi nổi. –

1

Hãy thử điều này:

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

Không, không có c hoặc C++ chức năng tiêu chuẩn để kiểm tra xem một số nguyên là một hình vuông hoàn hảo hay một hoàn hảo khối lập phương.

Nếu bạn muốn nó hoạt động nhanh và tránh sử dụng các phương thức float/double được đề cập trong hầu hết các câu trả lời, sau đó mã tìm kiếm nhị phân chỉ sử dụng các số nguyên. Nếu bạn có thể tìm thấy một n với n^2 < m < (n + 1)^2, thì m không phải là một hình vuông hoàn hảo. Nếu m là một hình vuông hoàn hảo, thì bạn sẽ tìm thấy một n với n^2 = m. Vấn đề được thảo luận here

0

Để xác định ô vuông tôi đã thử thuật toán này trong java. Với ít sự khác biệt về cú pháp, bạn cũng có thể làm điều đó trong C++. Logic là, sự khác biệt giữa hai ô vuông hoàn hảo liên tiếp sẽ tăng lên 2. Khác biệt (1,4) = 3, Khác biệt (4,9) = 5, Khác biệt (9,16) = 7, Khác biệt (16, 25) = 9 ..... tiếp tục. Chúng ta có thể sử dụng hiện tượng này để xác định các ô vuông hoàn hảo. mã Java là,

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

Để thực hiện việc xác định các hình vuông nhanh hơn chúng ta có thể sử dụng hiện tượng khác, tổng đệ quy của các chữ số của hình vuông hoàn hảo luôn là 1,4,7 hoặc 9. Vì vậy, một mã nhanh hơn nhiều có thể được ...

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

Đối vuông hoàn hảo bạn cũng có thể làm:

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

Đối với khối hoàn hảo bạn có thể:

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

Hy vọng điều này sẽ hữu ích.

+0

_IF_ đây là "về trả lại", tại sao không chỉ 'trở lại sqrt (n) == sàn (sqrt (n))'? (và tại sao thích 'tầng' thành' tròn'?) Sau đó, có 'int r = round (cbrt (n)); return n == r * r * r' - không cái nào trong số đó là 'được xác định trước', để _not cho kiến ​​thức năm 2016 của chúng ta_: [Câu trả lời của Chris] (http://stackoverflow.com/a/1549960/3789665). – greybeard

0

Chúng ta có thể sử dụng được xây dựng trong truc chức năng -

#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)); 
} 
Các vấn đề liên quan