【问题标题】:How can I tell if a number is a power of 10 in Kotlin or Java?在 Kotlin 或 Java 中,如何判断一个数字是 10 的幂?
【发布时间】:2017-04-08 02:19:38
【问题描述】:

我有一个数字(64 位整数),想知道它是否是 10 的纯幂。也就是说,1 后跟 0 或多个零。 有没有一种涉及将其转换为字符串的有效方法?


目前我正在这样做:

科特林

fun isPowerOf10(n: Long): Boolean {
    val logN = Math.log10(myInt.toDouble())
    return logN != Math.floor(logN)
}

Java

static boolean isPowerOf10(long n) {
    double logN = Math.log10((double) myInt);
    return logN != Math.floor(logN);
}

但由于在转换为双精度并采用 log10 时精度损失,isPowerOf10(999_999_999_999_999_999)(和负数版本)会失败,它会精确输出 18.0

【问题讨论】:

  • 考虑到案例很少,一个简单的switch可能是合理的。
  • 或者类似地简单地创建一个循环来预填充HashSet<Long>。无论您做什么,都不要使用双精度/对数逻辑进行纯整数检查,否则您将受到浮点精度的摆布,就像您在 999_999_...中看到的那样......
  • 您是否尝试过使用 BigDecimal 类型,我不知道是否有它的数学库,但它的精度比 Double 类型更好。
  • @jonhkr 我认为BigDecimal 在这种情况下与String 足够接近以避免它〜:P

标签: java math kotlin logarithm


【解决方案1】:

你可以做一个简单的while循环:

static boolean isPowerOf10(long n) {
    while(n > 1 && n % 10 == 0){
        n /= 10;
    }
    return n == 1;
}

或者甚至更好,检查 10 本身的幂,因为在很长的 (ref) 中只有 19 个:

public static boolean isPowerOf10(long n) {
  return 
    n == 1L
  || n == 10L
  || n == 100L
  || n == 1000L
  || n == 10000L
  || n == 100000L
  || n == 1000000L
  || n == 10000000L
  || n == 100000000L
  || n == 1000000000L
  || n == 10000000000L
  || n == 100000000000L
  || n == 1000000000000L
  || n == 10000000000000L
  || n == 100000000000000L
  || n == 1000000000000000L
  || n == 10000000000000000L
  || n == 100000000000000000L
  || n == 1000000000000000000L;
}  

【讨论】:

  • 你不能用n > 10 && n % 10 == 0 逃脱吗......它效率无限低:)
  • @juanpa.arrivillaga 否,因为对于 n=10,您将无法满足 n>10,因此 return 语句将返回 false,因为 10 == 1 为 false。
  • @juanpa.arrivillaga 10 的 0 次方是 1。while(n > 10 && n % 10 == 0){ n /= 10; } return n == 10; 在这种情况下不起作用
  • @juanpa.arrivillaga 我认为你可以做到 n > 9
  • @RikSchaaf d'oh!我在想什么!它实际上没有。如果小于 10 但不等于 1 的数字失败!
【解决方案2】:

这是检查数字是否为 10 的幂的另一种方法。此代码利用了一个事实,即只有少数数字适合 long 数据类型并且是 10 的幂。

public static boolean isPowerOfTen(long number){
        long[] powersOfTen = new long[] {
            1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000
        };

        return Arrays.binarySearch(powersOfTen, number) >= 0;
}

【讨论】:

  • 您可以使用HashMap 使其更快!! (假设您只需设置一次地图,但可以多次调用该方法。)
  • @ajb 正如你所指出的,我正在考虑设置一个哈希图。我只能想出将hasmap放在main()方法中并将其传递给函数或在我的类中创建静态hashmap虽然它们可以工作,但将仅由该函数使用的东西放在main方法中或创建hashmap作为一部分类的似乎不是一个优雅的解决方案。关于如何做得更好的任何建议?
  • 创建一个定义isPowerOfTen 方法的新类。该映射可以是您的类中的私有类变量 (static),如果您需要代码来执行此操作,可以使用静态初始化程序块进行初始化。
  • 您可以将数组设为static 以提高效率。
  • @ajb 为什么HashMap 比对排序数组的二分查找要快? IMO 他们执行大约相同数量的操作,并且数组版本具有更好的内存局部性
【解决方案3】:

要在 Kotlin 中制作 Rik Schaaf 回答的第二部分,您可以执行以下操作:

val Long.isPowerOfTen get() = when (this) {
    1L,
    10L,
    100L,
    1000L,
    10000L,
    100000L,
    1000000L,
    10000000L,
    100000000L,
    1000000000L,
    10000000000L,
    100000000000L,
    1000000000000L,
    10000000000000L,
    100000000000000L,
    1000000000000000L,
    10000000000000000L,
    100000000000000000L,
    1000000000000000000L -> true
    else -> false
}

【讨论】:

  • 这最终成为了我在 Kotlin 中使用的解决方案。谢谢!
【解决方案4】:

我们可以借助 String 类

return Math.pow(10,String.valueOf(x).length()-1) == x;

【讨论】:

    【解决方案5】:

    使用字符串的方法

    boolean isPowerOfTen(int n){
    
      if( n == 1)
        return true;
    
      String num = String.valueOf(n);
    
      if(num.charAt(0) == '1' && Integer.parseInt(num.substring(1)) == 0)
          return true;
      else
         return false;
    }
    

    这里,我们检查第一个字符是否为'1' AND
    丢弃第一个字符形成的子串是否为0。

    这不适用于 10^0,即 1。 处理了这个案子。

    这不如数学方法有效。

    【讨论】:

    • 哈哈很好。可以为 1 添加一个特殊情况
    • @Supuhstar 是的,处理了那个案子。
    【解决方案6】:

    也适用于负能量。

    boolean isPowerOf10(long number) {
        while (number % 10 == 0 && number != 0) {
            number = number / 10;
        }
        return Math.abs(number) == 1;
    }
    

    【讨论】:

      【解决方案7】:

      此解决方案也适用于负幂。例如 10 ^ -3

      public boolean isPowerOfTen(double n) {
         return (Math.pow(10,Math.log10(n)) == n);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-11
        • 2010-09-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 2013-01-11
        • 1970-01-01
        相关资源
        最近更新 更多