恒定时间长数的前N位数?

时间:2010-12-24 08:23:45

标签: algorithm clojure numbers

在Project Euler问题中,我需要处理可能有数百个数字的数字。我需要对前9位进行一些计算。

我的问题是:确定100位整数的前N位数的最快方法是什么?模数/余数的前N位数很容易。对于第一个数字,我可以按模数应用模数100次,或者我可以将数字转换为字符串并截断,但它们都是线性时间。还有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

您可以使用此功能计算位数:

(defn dec-digit-count [n]
  (inc (if (zero? n) 0
  (long (Math/floor (Math/log10 n))))))

现在我们知道有多少位数,我们只想先离开9.我们需要的是将数字除以10 ^(数字-9)或Clojure:

(defn first-digits [number digits]
  (unchecked-divide number (int (Math/pow 10 digits))))

并称之为:(first-digits your-number 9),我认为这是在不变的时间。我只是不确定log10的实现。但是,模数/循环解决方案肯定要快得多。

此外,还有一个更简单的解决方案。您只需复制并粘贴该号码的前9位数即可。

答案 1 :(得分:3)

也许你可以使用不是很长的数字,而是使用两个数字:[first-digits,last-digits]。对它们进行操作,每次都截断到所需的长度(条件的两倍,你的情况为9),第一个在右边,第二个在左边。 喜欢

222000333 * 666000555
147|852344988184|815

222111333 * 666111555
147|950925407752|815

所以你只能做两个小的计算:222 * 666 = 147 [852]和333 * 555 = [184] 815

但关于“ha”解决方案的评论与Project Euler最相关:)

答案 2 :(得分:1)

在Java中:

public class Main {
    public static void main(String[] args) throws IOException {
        long N = 7812938291232L;
        System.out.println(N / (int) (Math.pow(10, Math.floor(Math.log10(N)) - 8)));
        N = 1234567890;
        System.out.println(N / (int) (Math.pow(10, Math.floor(Math.log10(N)) - 8)));
        N = 1000000000;
        System.out.println(N / (int) (Math.pow(10, Math.floor(Math.log10(N)) - 8)));
    }
}

产量

781293829
123456789
100000000

答案 3 :(得分:0)

它可以帮助您first n digits of an exponentiation

和这个问题的答案

  

该算法具有O(b)的复杂性。但很容易将其更改为O(log b)