【问题标题】:BigInteger in ForLoop and Lists in JavaFor 循环中的 BigInteger 和 Java 中的列表
【发布时间】:2020-06-24 17:07:44
【问题描述】:

我正在尝试创建并返回一个 BigInteger 列表,该列表计算给定整数 n,作为降序斐波那契数的总和。例如,如果给定整数n = 8000,结果将返回[6765, 987, 233, 13, 2]

我已经编写了一个代码,可以将斐波那契数计算到一个列表中,而该数小于n,但我不太清楚如何实现其余部分。

【问题讨论】:

  • 好奇:您已经在使用BigInteger.ONE,为什么还要使用BigInteger.valueOf(1)?为什么使用BigInteger.valueOf(0) 而不是BigInteger.ZERO
  • 我正在尝试不同的方法来让程序运行,因为我只是在学习 Java。

标签: java list for-loop arraylist biginteger


【解决方案1】:

fib 函数对我来说似乎太复杂了。只需从最后两个元素的总和计算下一个元素:

public static List<BigInteger> fib(BigInteger n) {
    List<BigInteger> fibs = new ArrayList<>(asList(ONE, ONE));
    for (BigInteger last = ONE; last.compareTo(n) < 0; ) {
        last = last.add(fibs.get(fibs.size() - 2));
        fibs.add(last);
    }
    return fibs;
}

然后在列表中倒退并保留适合总和的元素:

public static void main(String[] args) {
    BigInteger n = BigInteger.valueOf(8000);
    List<BigInteger> fib = fib(n);
    BigInteger remaining = n;
    for (int i = fib.size() - 1; i >= 0; i--) {
        if (fib.get(i).compareTo(remaining) > 0) {
            fib.remove(i);
        } else {
            remaining = remaining.subtract(fib.get(i));
        }
    }
    Collections.reverse(fib);
    System.out.println(fib);
}

【讨论】:

  • 为什么会有valueOf(19)?
  • @BeanieLeung 那只是他用n = 19而不是n = 1000000进行测试
  • 想要投票,但结果不是“按降序排列”。
  • 是的,19 只是随机测试值,@Andreas 谢谢,我误读了这个要求。两者都固定。
【解决方案2】:

如果您打印 fibs,您会发现循环添加了两个 1,因此您应该删除 {fibs.add(BigInteger.ONE); fibs.add(BigInteger.ONE);} 行。

现在您已经拥有了所有斐波那契数,您可以从列表的末尾开始,并从 n 中减去数字,只要值不为负即可。

向后迭代列表的最简单方法是反转列表并正常迭代。

Collections.reverse(fibs);
for (BigInteger fib : fibs) {
    ...
}

您也可以在不反转列表的情况下执行此操作,方法是使用 ListIterator 向后迭代。

for (ListIterator<BigInteger> iter = fibs.listIterator(fibs.size()); iter.hasPrevious(); ) {
    BigInteger fib = iter.previous();
    ...
}

要找到可以从n 中减去的数字,只需保留仍需要减少的运行值,即原始b 的多少剩余

BigInteger remain = n;
for (BigInteger fib : fibs) {
    if (fib.compareTo(remain) <= 0) {  // if (fib <= remain)
        remain = remain.subtract(fib); //   remain -= fib;
    }
}

将减去的值添加到结果列表中,就完成了。

【讨论】:

  • 斐波那契数列的前两个数是 1 和 1,所以这就是两个 1 相加的原因
  • @BeanieLeung 但是代码中的 for 循环也添加了两个 1,因此您最终会在 fibs 中添加 四个 1,如果您这样做了,您会看到我所说的,即打印fibs
  • 啊,我明白了,感谢您指出这一点。所以我将值添加到结果列表中,但是当我运行程序时,列表中返回的最后一个元素是 0,这很奇怪,因为 0 不是元素是 fibs。你知道为什么会这样吗?
  • 我实际上什至没有得到正确的结果。现在当 n = 1000000 时,这是输出:[167960, 46567, 199, 55, 0]。我将更新问题中的代码,以便您查看我拥有的内容
  • @BeanieLeung 因为我看不到你的代码,所以我不知道。鉴于循环中的 if 语句中的 fib 永远不会是 0,我不知道你做了什么来得到这个结果。
猜你喜欢
  • 2017-03-19
  • 2011-12-08
  • 2019-05-14
  • 1970-01-01
  • 2018-08-19
  • 2012-09-02
  • 2014-02-22
  • 2020-05-12
  • 1970-01-01
相关资源
最近更新 更多