正常的方式是
int main(){
int a=2000,count=0,temp;
while(a!=0)
{
temp=a%10;
if(temp==0) count++
else break;
a/=10;
}
printf("%d",count);
}
有更有效的方法吗?
答案 0 :(得分:4)
对于32位整数(最大值2147483647),您最多只需要4次测试。对于64位,再添加一个16个零的测试。
从10的较大权力开始并逐渐减少:
int countTrailingZeros(int n)
{
int zeros = 0;
if((n % 100000000) == 0)
{
zeros += 8;
n /= 100000000;
}
if((n % 10000) == 0)
{
zeros += 4;
n /= 10000;
}
if((n % 100) == 0)
{
zeros += 2;
n /= 100;
}
if((n % 10) == 0)
{
zeros++;
}
return zeros;
}
这有一个更好的最坏情况表现,但如果你传递的数字的9/10没有尾随零,那么平均情况更糟。它只取决于您在典型情况下传递给它的值。
但是,如果您传递的数字的十分之九没有尾随零,那么您可能不必担心首先优化原始代码,因为它会在循环的第一次迭代中中断90%当时。
答案 1 :(得分:3)
您可以在此处调整二进制搜索的概念。 可能很难编码,但这是一个想法(因为你要求最有效的方式,我只是提出这个想法)。
我不只是谈论32位整数或64位整数。
当0的数量很高时,这种效果非常好,否则也应该是有效的。
说出您的电话号码是n
。
首先检查n%(10^1) == 0
是否
然后检查n%(10^2) == 0
是否
然后检查n%(10^4) == 0
是否为10^8 ....10^16
。我想你明白了。
所以最后你会得到一个点n % 10^(2x) !=0
,现在你知道没有。 0
的{{1}}位于x
和2x
之间。
所以再次从x
,x+1
,x+2
....开始进行二元搜索,直到找不到n % 10^(2y) != 0 (x < y <= 2x)
的情况。重复相同的过程。
时间复杂度(如果你有K 0
):
最好的情况是:
O(logK)
最坏的情况是:
ceil(log(K)) + ceil(log(k/2)) + ..... 1 = ~ O(logK)
答案 2 :(得分:2)
至少你通过每零只有一个分区来提高速度:
c = 1;
while (a % c == 0) {
c *= 10;
cout ++;
}
(可能你还需要在*=10
溢出时准确处理案例。
这仍然是同样的复杂性。但是,对于int
我怀疑你需要更高的复杂度,因为最大可能的零数非常小。