-2

检查整数中是否有0 (零)的最佳方法是什么

例如:

505 -> True
555 -> False
44444032 -> True
0000 -> True

我试过这个

public bool has0(int no)
{
    if(no==0)return true;
    while(no!=0)
    {
        if(no%10==0)return true;
        no=no/10;
    }
    return false;
}

这行得通,但是考虑到我需要专门针对大数调用此方法10 亿次这一事实,这需要花费大量时间

for(int i=0;i<1000000000;i++)has0(i);

那么,使用 , 或任何其他方式来检查数字中是否存在 0 的最佳方法|&什么^

谢谢..

4

4 回答 4

9

取模是一种昂贵的整数运算(类似于整数除法)。您可以通过查看数字是否为偶数来消除测试中一半的可能答案。没有奇数的模 10 等于 0。

if (((no & 0x1) == 0x00) && ((no % 10) == 0)) 返回真;

您将在偶数上支付更多费用,但在奇数上支付更少。因此,如果都是偶数,这将无济于事(实际上会受到伤害),但如果是 50/50 甚至 20/80(20% 奇数),您可能仍然会领先。

此外,整数乘法成本较低,因此您可以先进行除法并计算模 10。

while (no)
{
  if (no & 0x1))  // odd?
    no /= 10;
  else  // even
  {
    int nNext = no / 10;  // just do integer divide, and calculate modulo in next line
    if ((no - (10 * nNext)) == 0)  // replaces "more expensive" modulo operation with integer multiply and subtraction
      return true;
    no = nNext;
  }
}
于 2013-07-01T03:45:18.693 回答
4

虽然接受的答案肯定比原始代码快,但使用查找表的方法仍然会快得多。

在我的慢速笔记本电脑上,您的原始代码大约需要 28 秒来处理 2.5 亿个数字,而接受答案中的代码大约需要 23 秒。使用查找表,只用了7s多一点。

当您查看代码时,很明显为什么:

bool HasZero(int num)
{
    if (num < 100000) return lookup[num];

    int upperDigits = num / 100000;
    int lowerDigits = num - (upperDigits * 100000);

    return lookup[upperDigits] || lowerDigits < 10000 || lookup[lowerDigits];
}

该代码最多有一次除法、一次减法、一次乘法、两次比较和两次数组查找。即使经过优化,逐个数字地进行也可能比这糟糕。并且预先计算查找表需要很短的时间(< 1ms)。

请注意,如果您不使用 32 位整数,则代码将无法正常工作,因为那时您需要验证第三组数字(或将查找表的大小从 10^5 增加到 10^6 ; 我想它仍然会更快。)

于 2013-07-01T05:07:38.770 回答
0

只是一个小想法。除以常数可以用乘法和移位序列代替。如果您正在使用的编译器或虚拟机有线索,那么它会自己执行此操作。如果它很愚蠢,您可以通过手动插入乘法和移位序列来获得一些重大的加速。例如,对于 Java HotSpot 客户端 VM,我发现下面的技术(对非负 n 更正)比明显的除法方法(注释掉)快两倍多,快五倍作为使用模的原始循环。

static boolean has0(int n) {
    do {
        //int divided = n / 10;
        int divided = (int)((n * 0xCCCCCCCDL) >>> 35);
        if (divided * 10 == n) return true;
        n = divided;
    } while (n != 0);
    return false;
}

但是对于脑死比较少的Java HotSpot Server VM来说,明明的方式已经很快了,这个招也无济于事,甚至变慢了。不幸的是,对于这种非常低级的优化,您必须准备好针对不同的语言和语言实现重新调整它。

在尝试测量类似的东西之前,请阅读Java 中微基准测试的奇怪而奇妙的复杂性。

于 2013-07-11T15:08:39.550 回答
-4

如果 no==0,您的函数将返回 false。除此之外,我看不出你怎么能做得更好。

于 2013-07-01T03:28:24.127 回答