如何在Java中计算整数的末尾零?(例如:234000 => 3个零)

7
标题已经很明确了。 :)
1232 => 0
1231030 => 1
2000 => 3
34444400000 => 5

2
有几种方法可以做到这一点... 你会怎么做? - ControlAltDel
还有这个方法 Integer.numberOfTrailingZeros(num)。 - StackFlowed
3
numberOfTrailingZeros 函数计算的是零位的数量而非十进制数字。 - ajb
8个回答

11

如果一个数可以用 int/long 存储,只需检查该数字模 10 是否为 0 并计数:

long x = ...
if (x == 0) {
    return 0;
}
int counter = 0;
while (x % 10 == 0) {
    counter++;
    x /= 10;
}
如果某个数太大无法存储在 long 类型中,可以将其存储在一个 String 中,并从最后一个字符开始计算零的个数。
String s = ...
int counter = 0;
while(counter < s.length() && s.charAt(s.length() - 1 - counter) == '0') {
    counter++;
}

@WoodrowBarlow 先前进行了验证后修复。 - Luiggi Mendoza
第二个例子非常紧凑。如果可读性是一个问题,我建议将其转换为char数组,然后使用增强型循环进行迭代:for(char c : Integer.toString(i).toCharArray())需要额外的一行来作为条件,但更易读。对于您的不需要解析的示例,加1非常好。 - Dioxin
几年前,我认为这是最优解,但后来发现它并不是。@VinceEmigh - Luiggi Mendoza
1
@VinceEmigh 因为 toCharArray 必须复制当前 char[] 的内容以维护 String 的不可变性,这会带来一些小的性能损失,只是为了获得更短、更易读的代码。因此,如果 String 的内容不应被修改,则直接使用 String 类提供的方法即可。 - Luiggi Mendoza
可能有一种通过移位比特来推断更快的方法,但我不知道。 - chrisapotek
显示剩余3条评论

6

Integer类有一个内置函数来统计尾部零的个数。Javadocs

int trailingZeroes = Integer.numberOfTrailingZeros(int i);

jshell> Integer.numberOfTrailingZeros(1232); $1 ==> 4 - sideshowbarker
这个方法似乎是计算二进制中末尾零的数量,而不是十进制! - kennyg

4

三行:

int zeroes = 0
while(num%10 == 0 && num != 0) {
  zeroes++;
  num /= 10;
}

这里使用了模运算符。只要我们能够除以十没有余数,就增加计数器。


3

以下是另一种使用Java 8流的解决方案:

int trailingZeros = String.valueOf(number).chars()
        .reduce(0, (count, ch) -> (ch == '0') ? count + 1 : 0);

这将数字转换为IntStream。然后使用lambda函数对此流进行归约,每次出现非零字符时重置计数器。


这个缩减函数违反了关联性约束。因此,它将在并行流中出现错误。但即使它在顺序评估中产生预期结果,也必须被视为API的错误使用。 - Holger

2

你可以使用正则表达式:

Pattern pattern = Pattern.compile("(0+)$");
Matcher matcher = pattern.matcher(String.valueOf(123140000));
Integer trailingZeroes = 0;
if (matcher.find()) {
    trailingZeroes = matcher.group(1).length();
} 
System.out.println(trailingZeroes);

+1,不过你忘记处理没有尾随零的情况了 ;) - Nir Alfasi
你本可以写成(0*),这样就不需要单独的测试了。 - ajb
使用 matcher.end(1) - matcher.start(1) 可能比 matcher.group(1).length() 更高效,因为它避免了创建一个仅用于提取其长度的 String。此外,没有理由将结果装箱为 Integer;只使用 int 就足够了。 - Holger

0

我没有尝试过这段代码,但应该可以正常工作。

int counterForZeros=0;
for(long i=10;true;)
{
    if(num%i==0)
    {
        counterForZeros++;
        i*=10;
    }
    else 
    {
        break;
    }
}
System.out.println("Number of zeros in "+num+" is "+counterForZeros);

0

你可以将 int 转换为 String 并反向迭代,在找到一个非零的字符之前计算零的数量:

int countZeros(int x){
    String a = Integer.toString(x);
    int numOfZeros = 0;
    for(int i = a.length() - 1; i >= 0; i--)
        if (a.charAt(i) != '0') break;
        else numOfZeros ++;

    return numOfZeros;          
}

测试代码如下:
System.out.println(countZeros(25000)); 将会输出 3
System.out.println(countZeros(25)); 将会输出 0

希望这能有所帮助。


0

嗯,如果这是一个比赛,看看谁能用最少的行数完成它:

trailingZeroes = String.valueOf(num).length() - String.valueOf(num).replaceAll("0*$","").length();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接