0

我需要查找一个数字中是否包含 0。到目前为止,我已经尝试将数字与 10 取模,然后将商除以 10,然后重复此过程直到数字为 0。正在将此数字转换为字符串并使用 .contains 搜索此字符串() 方法更高效?

我的代码:

boolean zero(int n) {
    if(n == 0)
        return true;

    while(n > 0) {
        if(n % 10 == 0)
            return true;
        n = n/10;
    }
    return false;
}

任何帮助,将不胜感激。

4

1 回答 1

4

好吧,实际上,想想每个数字的字符串是如何“创建”的:通过除数和 10 的模数。所以 int-to-String 转换实际上将执行您正在执行的相同任务。

这是 的源代码Integer.getChars(),它是通过调用的Integer.toString(),以及其他一些缓冲区管理:

static void getChars(int i, int index, char[] buf) {
    int q, r;
    int charPos = index;
    char sign = 0;

    if (i < 0) {
        sign = '-';
        i = -i;
    }

    // Generate two digits per iteration
    while (i >= 65536) {
        q = i / 100;
    // really: r = i - (q * 100);
        r = i - ((q << 6) + (q << 5) + (q << 2));
        i = q;
        buf [--charPos] = DigitOnes[r];
        buf [--charPos] = DigitTens[r];
    }

    // Fall thru to fast mode for smaller numbers
    // assert(i <= 65536, i);
    for (;;) {
        q = (i * 52429) >>> (16+3);
        r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
        buf [--charPos] = digits [r];
        i = q;
        if (i == 0) break;
    }
    if (sign != 0) {
        buf [--charPos] = sign;
    }
}

如您所见,对于大于 65536 的数字,它使用并改进了除法转换循环。对于较低的数字(或者一旦原始数字被削减),就会进行一些重度优化(位移位和字节掩码)并继续进行。除法的成本通常要高得多,比位移慢大约 20 到 60 倍。所以最后一部分真的很快。但这只是5位数,那会有多大的影响呢?

还要考虑内存管理。如果您的系统在所有内核上保持 100% 运行,则 JVM 可能会遇到速度障碍,并且当(如果)可能必须发生垃圾收集时,GC 引起的“强制”暂停可能会消除所有速度优势。(测试这应该是分钟内的长期测试)。

您也可以考虑将问题/任务拆分到多个线程中。最简单的方法是使用 java 1.8-new 流。或者你有你自己的并行器/分离器和你自己的任务数组/队列。可能几乎是任务速度的 n 倍,其中 n 是您可以使用的 CPU 内核数。

正如其他人所说,实际上最好自己测试速度。最好写一个运行大约 10 秒的测试。这足够长,可以为您提供稳定的估计和 JIT 优化,并且足够短,不会无聊到地狱。

另一方面,通常最好以一种明显的、非神秘的、易于维护的方式来解决问题。所以如果我必须实现它,我会测试,如果差异小于 5 倍,我会只坚持数字。没有附加字符串:-D

于 2021-03-19T23:22:37.880 回答