【问题标题】:java library similar to c++ map类似于 c++ map 的 java 库
【发布时间】:2016-03-21 12:28:03
【问题描述】:

为了使用记忆法查找第 n 个斐波那契数,我找到了一个在 c++ 中使用 map 的代码。

我曾尝试在 java 中转换此代码,但失败了。

c++ 代码:

#include <bits/stdc++.h>   

typedef long long int ll;  

map<ll, ll> mp;  
ll M = 1000000007;       

long long fibonacci(long long n) {  
   if (mp.count(n))return mp[n];  
   long long k=n/2;  
   if (n%2==0) {   
      return mp[n] = fibonacci(k)*(fibonacci(k+1)+fibonacci(k-1)) % M;  
    } else {   
       return mp[n] = (fibonacci(k+1)*fibonacci(k+1) + fibonacci(k)*fibonacci(k)) % M;  
    }  
 }  

 int main()  
{  
   mp[0]=mp[1]=1;  
   ll t;  
   scanf("%lld",&t);
   printf("%lld\n",fibonacci(t));  
}   

我在 java 中使用HashMap 尝试了相同的代码。

java代码:

static HashMap<Long,Long> hm=new HashMap<Long,Long>();

static long  f(long n) {
  if (hm.containsKey(n)) return hm.get(n);
  long k=n/2;
  if (n%2==0) {
     return hm.put(n,f(k)*(f(k+1)+f(k-1)) % M);        
  } else { 
     return hm.put(n, (f(k+1)*f(k+1) + f(k)*f(k)) % M);
   }
 }



  public static void main(String[] args) throws IOException {
    hm.put(1L,1L);
    hm.put(0L,1L);
    long b=f(2L);
  }

但是java中的这段代码给出了StackOverflowError

我在 java 中使用 LinkedHashMapTreeMap 尝试了这段代码,两者都给出了相同的错误。

我必须使用哪个类与 c++ 中的map 相同?

请有人解释一下map 在 C++ 中的工作原理。

编辑
查看javac++ 中代码的输出
c++:c++ code
爪哇:java code

【问题讨论】:

  • 这是一种非常复杂的实现方式。为什么不使用循环来记录适合数组中long 的所有值。这将花费 3 毫秒,不仅更快,而且更简单。
  • 我正在解决这个问题spoj.com/problems/POWFIB
  • 我尝试过使用矩阵乘法,但它给出了超出时间限制

标签: java c++ stl hashmap


【解决方案1】:

要记住适合long 的所有可能的斐波那契数,您可以使用一个简单的数组。

static final int[] FIB = new int[100_000_000];
static final intM = 1000000007;

static {
    long start = System.currentTimeMillis();
    FIB[1] = FIB[2] = 1;
    for (int i = 3; i < FIB.length; i++) {
        int l = FIB[i - 1] + FIB[i - 2];
        while (l >= M)
            l -= M;
        FIB[i] = l;
    }
    long time = System.currentTimeMillis() - start;
    System.out.printf("Took %.3f seconds to build table of %,d fibonacci values%n", time/1e3, FIB.length);
}

public static long fibonacci(int n) {
    return FIB[n];
}

public static void main(String[] args) {
}

打印

Took 0.648 seconds to build table of 100,000,000 fibonacci values

这将为数组使用 400 MB 的内存,这比任何映射实现都更有效。

【讨论】:

  • 输入在 10^8 范围内
  • 测试用例数在10^5左右
  • @priyank 在这种情况下,您需要使用公式计算值。 math.hmc.edu/funfacts/ffiles/10002.4-5.shtml 没有足够的内存来记住这么多的值。 BTW long 不会将结果存储在 fib(92) 之上。
  • 问题是找到第 n 个斐比那契数 mod 10^9+7。我在解决方案中使用了 %M
  • @priyank fib(10^8) 中的位数大约是 20,898,764 所以要记住所有这些值,您平均需要大约 10^8 * 4 MB 或 4 * 10 ^ 14 字节或 400 TB。
【解决方案2】:

StackOverflowError 发生在堆叠的方法调用过多时,它会被虚拟机抛出。这根本不是HashMap 的问题。

来自文档:

由于应用程序递归而发生堆栈溢出时引发 太深了。

您可以通过使用-Xss 标志来增加 JVM 的堆栈大小,或者您可以尝试使用更好的算法,或者查看此算法以检查它是否真的等同于 c++ 版本...但是要么方式,我认为您只是过于复杂了,有更简单的方法可以获得相同的结果。

您还可以查看this question,了解递归斐波那契方法的外观。


编辑:检查this link,它显示了如何使用 memoization 和 Java 获得第 n 个数字。

另外,请查看this question,关于如何获得大的第 n 个斐波那契数,有很多不同方法的答案。


另一种方法

使用List&lt;Long&gt; 作为缓存。

private static List<Long> cache = new ArrayList<Long>();

/*
 * Java Program to calculate Fibonacci numbers with memorization
 * This is quite fast as compared to previous Fibonacci function
 * especially for calculating factorial of large numbers.
 */
public static int improvedFibo(int number){
    Integer fibonacci = cache.get(number);
    if(fibonacci != null){
        return fibonacci; //fibonacci number from cache
    }
    //fibonacci number not in cache, calculating it
    fibonacci = fibonacci2(number);

    //putting fibonacci number in cache for future request 
    cache.put(number, fibonacci); 
    return fibonacci;
}

Taken from here.

您也可以查看this question 以获取另一个示例。

【讨论】:

  • 我认为问题是 c++ 中的 map 与 java 中的 Hashmap 不同。我是 C++ 新手,所以我不知道 C++ 中的 map 是如何工作的
  • stackoverflowerror 是因为每次调用 f(k+1) 而在 c++ 代码中它不会给出相同的错误.. 我不明白为什么在 c++ 中会发生这种情况
  • 我相信唯一的区别是c++map比JavaHashMap使用更少的内存。
  • 看看这个c++实现ideone.com/rTjjw6。这里 printf in function 用于调试目的..它只调用了两次函数:)
  • 虽然 java ideone.com/Yt59Pb 中的相同函数在 n=2 时继续调用它自己
猜你喜欢
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
相关资源
最近更新 更多