【问题标题】:Large Optimized IO processing in JavaJava 中的大型优化 IO 处理
【发布时间】:2016-07-15 07:22:14
【问题描述】:

10^18 阶的输入 n 和输出应该是设置位仅为 2 的所有数字的总和。例如n = 5 设置位是 101--> 2 设置位。对于 n = 1234567865432784,如何优化下面的代码?

class TestClass 
{
    public static void main(String args[])
    {
        long N,s=0L;
            Scanner sc = new Scanner(System.in);

            N=sc.nextLong();
            for(long j = 1; j<=N; j++)
            {
                long b = j;
                int count = 0;
                while(b!=0)
                {
                    b = b & (b-1);
                    count++;
                }

                if(count == 2)
                {
                    s+=j;
                    count = 0;
                }
                else
                {   
                    count = 0;
                    continue;
                }
            }
            System.out.println(s%1000000007);
            s=0L;
    }

}

【问题讨论】:

  • 您是否只是编辑了您提出的问题以使其成为一个完全不同的问题?
  • 我先输入了一个错误的问题,Leo,请帮我解决这个问题。
  • 我需要快速 IO 技术方面的帮助来读取大输入和打印大输出。在这方面也需要帮助。

标签: java algorithm io


【解决方案1】:

Java有一个功能

if (Integer.bitCount(i) == 2) { ...

但是考虑一下:这是要检查的很多数字。

生成所有只有两位设置的数字怎么样?

设置n的ith和jth位:

int n = (1 << i) | (1 << j); // i != j

现在考虑 31² 步,N 步还不是 1000 步。

因为这是家庭作业,我的建议是:

尝试扭转问题,做最少的工作,退后一步,找到智能方法,搜索数学核心。 然后享受。

下一次,不要浪费自己的成功时刻。

【讨论】:

  • 我需要快速 IO 技术方面的帮助来读取大输入和打印大输出。我认为你解决这个问题的方法很优雅。我正在尝试实现这一点,如果我不明白,我可能会要求更多解释。
  • @sagnikDas 我实际上在 3 小时前的回答中提供了此处描述的实现。不知道你说的IO是什么意思。我在您的问题中找不到任何与 IO 相关的内容。
  • 我理解我没有特别提到 IO 的问题。我后来要求,如果我们可以使用像 BufferedReader 或 BufferedInputStream 这样的快速 io 技术......来接受我认为比 Scanner 更快的输入。我需要知道实现技术
  • 我讨厌有人对一个特别糟糕的问题给出了很好的答案,而 OP 说“不,它不能 100% 解决我的问题”并且没有投票或勾选它。跨度>
  • @LeoIzen 感谢您的同情。如果它不符合 OP 的需要,那对我来说很好。请注意,我没有给出完整的答案,“尝试……”可能听起来有点刺耳。 (我的积分已经太多了,一个人不可能都赢。)
【解决方案2】:

您可能有足够的时间考虑 Joop Eggen 的建议, 这就是我会怎么做(这是我认为乔普所描述的):

import java.util.Scanner;

public class Program {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextLong();

        long sum = 0;

        for (int firstBitIndex = 0; firstBitIndex < 64; firstBitIndex++) {
            long firstBit = 1L << firstBitIndex;
            if (firstBit >= n)
                break;
            for (int secondBitIndex = firstBitIndex + 1; secondBitIndex < 64; secondBitIndex++) {
                long value = firstBit | (1L << secondBitIndex);
                if (value > n)
                    break;
                sum += value;
            }
        }
        System.out.println(sum % 1000000007);
        sc.close();
    }
}

【讨论】:

  • @JoopEggen 你说得对,我忘记了“L”。我已经修改了代码。无论如何都必须非常小心,因为最后一位会切换符号,这肯定会干扰 >n 比较。可悲的是 Java 没有正确的无符号类型...
  • 在符号上:N = 10^18 = 10^3^6
  • @JoopEggen 哦,是的,忘记了
【解决方案3】:

Java 提供了类BigInteger,其中包含一个方法nextProbablePrime()。这意味着你可以这样做:

BigInteger n = new BigInteger(stringInputN);
BigInteger test = BigInteger.valueOf(2);
BigInteger total = BigInteger.valueOf(0);
while (test.compareTo(n) < 0){
    total = total.add(test);
    test = test.nextProbablePrime();
}
System.out.println(total);

这有极低的概率得到错误​​的答案(但非零),所以你可能想运行两次只是为了仔细检查。不过,它应该比手动迭代要快。

【讨论】:

    猜你喜欢
    • 2011-06-05
    • 2023-03-13
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多