【问题标题】:Perfect square and perfect cube完美的正方形和完美的立方体
【发布时间】:2010-12-05 17:11:47
【问题描述】:

c++中是否有任何预定义的函数来检查数字是否是任何数字的平方和立方体是否相同..

【问题讨论】:

    标签: c++ algorithm math integer integer-arithmetic


    【解决方案1】:

    没有,但写一个很容易:

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

    【讨论】:

    • 由于浮点错误,这并不总是有效:如果 sqrt()cbrt() 恰好返回小于实际根的 epsilon,则转换为整数将截断它,并且检查将失败。为了完全避免这种情况,您还需要检查n == (root + 1) * (root + 1) 是否适用于平方根情况,或者n == (root + 1) * (root + 1) * (root + 1) 是否适用于立方根情况。
    • 天哪,这让我头疼。我一直在寻找“根”函数,直到我意识到你只是在初始化一个整数......我非常不喜欢你的编码风格。
    • @Mark:你可以随心所欲地不喜欢它,但它是 C++ 中“更标准”的初始化风格;我认为它被称为“构造函数语法”或类似的东西。即,如果您正在构建一个对象,例如,它需要多个构造函数参数,那么无论如何您都必须使用该语法。我不喜欢为数字类型做一个特殊的例外,所以我也对它们使用构造函数语法。
    • 天哪,我刚回到这个问题并试图留下相同的评论,然后注意到其他人已经这样做了,然后试图给他们投票但找不到向上箭头,然后看着用户,并意识到是我。检查abs(root-round(root)) &lt;= epsilon而不是相乘不是更快吗?
    • 这称为直接初始化。但是大括号初始化比使用括号更可取,因为它消除了大多数令人头疼的解析问题。
    【解决方案2】:

    sqrt(x),或者一般来说,pow(x, 1./2)pow(x, 1./3)

    例如:

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

    编辑:或一般来说:

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

    【讨论】:

    • 使用 pow(x, 1./3) 的问题是 1/3 没有精确的浮点表示,所以你不是“真的”得到立方根。 C99 以后有cbrt,应该可以更好地获取立方根。
    • 我想。但是pow 更容易泛化,而且很容易纠正浮点错误。
    【解决方案3】:

    不,没有标准的 c 或 c++ 函数来检查整数是完美的正方形还是完美的立方体。

    如果您希望它快速并避免使用大多数答案中提到的浮点/双精度例程,那么只使用整数编写二进制搜索。如果你能找到一个 n^2 here

    【讨论】:

      【解决方案4】:

      试试这个:

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

      【讨论】:

        【解决方案5】:

        最有效的答案可能是这个

            int x=sqrt(num)
            if(sqrt(num)>x){
            Then its not a square root}
            else{it is a perfect square}
        

        此方法之所以有效,是因为 x 是一个 int,它会下拉小数部分以仅存储整数部分。如果一个数是整数的完全平方,则它的平方根将是整数,因此 x 和 sqrt(x) 将相等。

        【讨论】:

          【解决方案6】:

          为了识别正方形,我在 java 中尝试了这个算法。几乎没有语法差异,您也可以在 C++ 中做到这一点。 逻辑是,每两​​个连续完美正方形之间的差异继续增加 2. Diff(1,4)=3 , Diff(4,9)=5 , Diff(9,16)= 7 , Diff(16,25 )= 9 ..... 继续。 我们可以利用这种现象来识别完美的正方形。 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;
           }  
          

          为了更快地识别正方形,我们可以使用另一种现象,完美正方形的递归数字总和始终为 1、4、7 或 9。 所以一个更快的代码可以...

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

          【讨论】:

            【解决方案7】:

            对于完美的正方形,您也可以这样做:

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

            对于完美的立方体,您可以:

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

            希望这会有所帮助。

            【讨论】:

            • 如果这是“关于回归”,为什么不只是return sqrt(n)==floor(sqrt(n))? (为什么更喜欢floor 而不是round?)然后,有int r = round(cbrt(n)); return n == r*r*r - 没有一个是predefined我们 2016 年不知道Chris' answer
            • 由于浮点舍入,这不是进行多维数据集检查的好方法。这将在n == 27 上失败:Try it online!
            【解决方案8】:

            我们可以使用内置的truc 函数-

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

            【讨论】:

            • 多维数据集根检查在 27 日失败。
            【解决方案9】:
            bool isSquare(int n) {
                return floor(sqrt(n)) == ceil(sqrt(n));
            }
            
            bool isQube(int n) {
                return floor(cbrt(n)) == ceil(cbrt(n));
            }
            

            【讨论】:

            • 您的立方根检查器在某些值处失败,例如 27。
            • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-08-23
            • 2017-07-29
            • 2016-12-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-01-17
            相关资源
            最近更新 更多