java library similar to c++ map - java

To find nth fibonacci number using memoization I found one code which uses map in c++.
I have tried to convert this code in java but it fails .
code in 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));
}
I have tried same code in java using HashMap.
code in 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);
}
but this code in java gives StackOverflowError.
I have tried this code using LinkedHashMap and TreeMap in java both gives same error.
Which class I have to use which works same as map in c++?
Please someone explain how map work in c++.
EDIT
look at the output of code in java and c++
c++: c++ code
java: java code

To memorize all the possible fibonacci numbers which fit into a long you can use a simple array.
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) {
}
prints
Took 0.648 seconds to build table of 100,000,000 fibonacci values
This would use 400 MB of memory for the array which is more efficient than any map implementation.

A StackOverflowError happens when you have too many methods calls stacked, it's thrown by the virtual machine. It's not a HashMap problem at all.
From the docs:
Thrown when a stack overflow occurs because an application recurses
too deeply.
You could either increase the stack size of your JVM by using the -Xss flag, or you could try to use a better algorithm, or review this one to check if it's really equivalent to the c++ version... But either way, I think you're just overcomplicating this, there are simpler ways of getting the same result.
You can also check this question on how a recursive fibonacci method looks like.
EDIT: Check this link, it shows how you can get the nth number using memoization and Java.
Also, check this question, there are lots of answers with different methods on how to get a large nth fibonacci number.
Another way of doing this
Use a List<Long> as a cache.
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.
You can also check this question for another example.

Related

Why do I need to mention the method name? Why not simply (n-1)*n?

Here is the example code, I came across this in Java The Complete reference, 9th edition.
// A simple example of recursion.
class Factorial { // this is a recursive method
int fact(int n) {
int result;
if(n==1) return 1;
result = fact(n-1) * n; //This is my question, why not just (n-1)*n?
return result;
} }
class Recursion {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.println("Factorial of 3 is " + f.fact(3)); //
} }
Because otherwise it will not call the function again and will just calculate n*(n-1) and exit. For 3 this will do 3x2=6, which is in fact equal to 3!. However, if you try it with 4!, then your change it will return 4x3=12, when in fact to calculate 4! it should work out 4x3x2x1=24.
Answer is pretty simple, because most factorial algoritms based on recursive method, that means that fucntion calls itself, if write (n -1) * n it will multiply only one time and the result will be wrong(not n!).
There are a lot of articles about recursive methods and how factorial works in particularly. Read those for example:
https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursive-factorial
https://introcs.cs.princeton.edu/java/23recursion/

Not getting output for simple java program to find greatest prime factor

class LargestPrimeFactor{
public static void main(String args[]){
long p=0L;
long n=600851475143L;
for(long i=2L;i<(n/2);i++){
if((BigInteger.valueOf(i)).isProbablePrime(1)){
if(n%i==0){
p=i;
}
}
}
System.out.println(p);
}
}
It's problem 3 from Project Euler. I compiled it and no errors showed up. But am not getting any output. Whats the reason?
It is working (just add a print method inside the loop to check i for example).
You are currently using the Brute-Force method:
http://www.mathblog.dk/project-euler-problem-3/
If you visit the link the guy tells you an alternative solution for it.
The problem I see without having much knowledge about this is
that the operations you currently do are way too many.
You got the value "600851475143" stored in a long datatype and you try to
reach the half (300425737571,5) using the int i (counter in your for-loop).
https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#MAX_VALUE
This tells us: "A constant holding the maximum value an int can have,
2^(31)-1." = 2147483647
This is just 0,00715 (0,7%) of what you actually need.
So this leads us to an "Overflow".
Think of using the alternative method (first link)
and change the counter of your for-loop to type "long".
int maximum value is 2147483647 which is smaller than 600851475143/2
when index i reaches max value it will wrap around and start with negative number (-2147483648)
you should make your index i a long value
You have an infinite loop on the second for iteration you can only see it when you add logging before the end of the loop. It's not because it's not printing the value, when you stare at the console the iterator is still circling through 6857.
Try running the code with extra logging below.
public static void main(String args[]) {
int p = 0;
long n = 600851475143L;
for (int i = 2; i < (n / 2); i++) {
if ((BigInteger.valueOf(i)).isProbablePrime(1)) {
if (BigInteger.valueOf(n % i).compareTo(BigInteger.valueOf(0)) == 0) {
p = i;
System.out.println("Check == true Iteration"+p);
}
System.err.println("Second iterator"+p);
}
}
System.out.println("Final Value of P: "+p);
}
EDITED
The int data type can store values upto 2,147,483,647. To store numbers beyond that, use long.
long n = 600851475143L;
Not 600851475143 L, as that one space before L causes the system to not register it.
Also, int i in the for loop should be long i.

Fast real valued random generator in java

java.util.Random.nextDouble() is slow for me and I need something really fast.
I did some google search and I've found only integers based fast random generators. Is here anything for real numbers from interval <0, 1) ?
If you need something fast and have access to Java8, I can recommend the java.utils SplittableRandom. It is faster (~twice as fast) and has better statistical distribution.
If you need a even faster or better algorithm I can recommend one of these specialized XorShift variants:
XorShift128PlusRandom (faster & better)
XorShift1024StarPhiRandom (similar speed, even longer period)
Information on these algorithms and their quality can be found in this big PRNG comparison.
I made an independent Performance comparison you can find the detailed results and the code here: github.com/tobijdc/PRNG-Performance
Futhermore Apache Commons RNG has a performance test of all their implemented algoritms
TLDR
Never use java.util.Random, use java.util.SplittableRandom.
If you need faster or better PRNG use a XorShift variant.
You could modify an integer based RNG to output doubles in the interval [0,1) in the following way:
double randDouble = randInt()/(RAND_INT_MAX + 1.0)
However, if randInt() generates a 32-bit integer this won't fill all the bits of the double because double has 53 mantissa bits. You could obviously generate two random integers to fill all mantissa bits. Or you could take a look at the source code of the Ramdom.nextDouble() implementation. It almost surely uses an integer RNG and simply converts the output to a double.
As for performance, the best-performing random number generators are linear congruential generators. Of these, I recommend using the Numerical Recipes generator. You can see more information about LCGs from Wikipedia: http://en.wikipedia.org/wiki/Linear_congruential_generator
However, if you want good randomness and performance is not that important, I think Mersenne Twister is the best choice. It also has a Wikipedia page: http://en.wikipedia.org/wiki/Mersenne_Twister
There is a recent random number generator called PCG, explained in http://www.pcg-random.org/. This is essentially a post-processing step for LCG that improves the randomness of the LCG output. Note that PCG is slower than LCG because it is simply a post-processing step for LCG. Thus, if performance is very important and randomness quality not that important, you want to use LCG instead of PCG.
Note that none of the generators I mentioned are cryptographically secure. If you need use the values for cryptographical applications, you should be using a cryptographically secure algorithm. However, I don't really believe that doubles would be used for cryptography.
Note that all these solutions miss a fundamental fact (that I wasn't aware of up to a few weeks ago): passing from 64 bits to a double using a multiplication is a major loss of time. The implementation of xorshift128+ and xorshift1024+ in the DSI utilities (http://dsiutils.di.unimi.it/) use direct bit manipulation and the results are impressive.
See the benchmarks for nextDouble() at
http://dsiutils.di.unimi.it/docs/it/unimi/dsi/util/package-summary.html#package.description
and the quality reported at
http://prng.di.unimi.it/
Imho you should just accept juhist's answer - here's why.
nextDouble is slow because it makes two calls to next() - it's written right there in the documentation.
So your best options are:
use a fast 64 bit generator, convert that to double (MT, PCG, xorshift*, ISAAC64, ...)
generate doubles directly
Here's an overly long benchmark with java's Random, an LCG (as bad as java.util.Random), and Marsaglia's universal generator (the version generating doubles).
import java.util.*;
public class d01 {
private static long sec(double x)
{
return (long) (x * (1000L*1000*1000));
}
// ns/op: nanoseconds to generate a double
// loop until it takes a second.
public static double ns_op(Random r)
{
long nanos = -1;
int n;
for(n = 1; n < 0x12345678; n *= 2) {
long t0 = System.nanoTime();
for(int i = 0; i < n; i++)
r.nextDouble();
nanos = System.nanoTime() - t0;
if(nanos >= sec(1))
break;
if(nanos < sec(0.1))
n *= 4;
}
return nanos / (double)n;
}
public static void bench(Random r)
{
System.out.println(ns_op(r) + " " + r.toString());
}
public static void main(String[] args)
{
for(int i = 0; i < 3; i++) {
bench(new Random());
bench(new LCG64(new Random().nextLong()));
bench(new UNI_double(new Random().nextLong()));
}
}
}
// straight from wikipedia
class LCG64 extends java.util.Random {
private long x;
public LCG64(long seed) {
this.x = seed;
}
#Override
public long nextLong() {
x = x * 6364136223846793005L + 1442695040888963407L;
return x;
}
#Override
public double nextDouble(){
return (nextLong() >>> 11) * (1.0/9007199254740992.0);
}
#Override
protected int next(int nbits)
{
throw new RuntimeException("TODO");
}
}
class UNI_double extends java.util.Random {
// Marsaglia's UNIversal random generator extended to double precision
// G. Marsaglia, W.W. Tsang / Statistics & Probability Letters 66 (2004) 183 – 187
private final double[] U = new double[98];
static final double r=9007199254740881.0/9007199254740992.;
static final double d=362436069876.0/9007199254740992.0;
private double c=0.;
private int i=97,j=33;
#Override
public double nextDouble(){
double x;
x=U[i]- U[j];
if(x<0.0)
x=x+1.0;
U[i]=x;
if(--i==0) i=97;
if(--j==0) j=97;
c=c-d;
if(c<0.0)
c=c+r;
x=x-c;
if(x<0.)
return x+1.;
return x;
}
//A two-seed function for filling the static array U[98] one bit at a time
private
void fillU(int seed1, int seed2){
double s,t;
int x,y,i,j;
x=seed1;
y=seed2;
for (i=1; i<98; i++){
s= 0.0;
t=0.5;
for (j=1; j<54; j++){
x=(6969*x) % 65543;
// typo in the paper:
//y=(8888*x) % 65579;
//used forthe demo in the last page of the paper.
y=(8888*y) % 65579;
if(((x^y)& 32)>0)
s=s+t;
t=.5*t;
}
if(x == 0)
throw new IllegalArgumentException("x");
if(y == 0)
throw new IllegalArgumentException("y");
U[i]=s;
}
}
// Marsaglia's test code is useless because of a typo in fillU():
// x=(6969*x)%65543;
// y=(8888*x)% 65579;
public UNI_double(long seed)
{
Random r = new Random(seed);
for(;;) {
try {
fillU(r.nextInt(), r.nextInt());
break;
} catch(Exception e) {
// loop again
}
}
}
#Override
protected int next(int nbits)
{
throw new RuntimeException("TODO");
}
}
You could create an array of random doubles when you init your program and then just repeat it. This is much faster but the random values reapeat themselfs.

Java fastest way to get matching range

I have a set of integer ranges, which represent lower and upper bounds of classes. For example:
0..500 xsmall
500..1000 small
1000..1500 medium
1500..2500 large
In my case there can be over 500 classes. These classes do not overlap, but they can differ in size.
I can implement finding the matching range as a simple linear search through a list, for example
class Range
{
int lower;
int upper;
String category;
boolean contains(int val)
{
return lower <= val && val < upper;
}
}
public String getMatchingCategory(int val)
{
for (Range r : listOfRanges)
{
if (r.contains(val))
{
return r.category;
}
}
return null;
}
However, this seems slow; as I need on average N/2 look-ups. If the classes were equally sized, I could use division. Is there a standard technique to find the correct range faster?
What you are looking for is a SortedMap and its methods tailMap and firstKey. Check out the documentation for full details.
The advantage of this approach over plain arrays is in the ease of maintaining your ranges: you can insert/remove new boundaries at any point with almost no runtime cost; with arrays it means copying both parallel arrays in full.
Update
I've written code for both variants and benchmarked it:
#State(Scope.Thread)
#OutputTimeUnit(TimeUnit.MICROSECONDS)
public class BinarySearch
{
static final int ARRAY_SIZE = 128, INCREMENT = 1000;
static final int[] arrayK = new int[ARRAY_SIZE];
static final String[] arrayV = new String[ARRAY_SIZE];
static final SortedMap<Integer,String> map = new TreeMap<>();
static {
for (int i = 0, j = 0; i < arrayK.length; i++) {
arrayK[i] = j; arrayV[i] = String.valueOf(j);
map.put(j, String.valueOf(j));
j += INCREMENT;
}
}
final Random rnd = new Random();
int rndInt;
#Setup(Level.Invocation) public void nextInt() {
rndInt = rnd.nextInt((ARRAY_SIZE-1)*INCREMENT);
}
#GenerateMicroBenchmark
public String array() {
final int i = Arrays.binarySearch(arrayK, rndInt);
return arrayV[i >= 0? i : -(i+1)];
}
#GenerateMicroBenchmark
public String sortedMap() {
return map.tailMap(rndInt).values().iterator().next();
}
}
Benchmark results:
Benchmark Mode Thr Cnt Sec Mean Mean error Units
array thrpt 1 5 5 10.948 0.033 ops/usec
sortedMap thrpt 1 5 5 5.752 0.070 ops/usec
Interpretation: array search is only twice as fast and this factor is quite stable across array sizes. In the presented code the array size is 1024 and the factor is 1.9. I've also tested with array size 128, where the factor is 2.05.
Here, Arrays.binarySearch is your friend. Simply put all the boundaries in and handle the possible cases. Assuming you ranges leave no holes between them, you only need to put the upper bounds in.
For you example
0..500 xsmall
500..1000 small
1000..1500 medium
1500..2500 large
you'd use
int[] boundaries = {500, 1000, 1500, 2500};
and look up the input. Handle the two cases (found/not found) and you're done. Forget about ranges, they're nice but they don't fit you problem.
Update
I also wrote a benchmark and no matter how I try I'd lose my bet as the ratio is about 3 rather than 5. The strange things like S001024 in my results stand for the size 1024.

All possible values of int from the smallest to the largest, using Java

Write a program to print out all possible values of int data type from the smallest to the largest, using Java.
Some notable solutions as of 8th of May 2009, 10:44 GMT:
1) Daniel Lew was the first to post correctly working code.
2) Kris has provided the simplest solution for the given problem.
3) Tom Hawtin - tackline, came up arguably with the most elegant solution.
4) mmyers pointed out that printing is likely to become a bottleneck and can be improved through buffering.
5) Jay's brute force approach is notable since, besides defying the core point of programming, the resulting source code takes about 128 GB and will blow compiler limits.
As a side note I believe that the answers do demonstrate that it could be a good interview question, as long as the emphasis is not on the ability to remember trivia about the data type overflow and its implications (that can be easily spotted during unit testing), or the way of obtaining MAX and MIN limits (can easily be looked up in the documentation) but rather on the analysis of various ways of dealing with the problem.
class Test {
public static void main(String[] args) {
for (int a = Integer.MIN_VALUE; a < Integer.MAX_VALUE; a++) {
System.out.println(a);
}
System.out.println(Integer.MAX_VALUE);
}
}
Am I hired?
Simplest form (minimum code):
for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
System.out.println(i);
}
No integer overflow, no extra checks (just a little more memory usage, but who doesn't have 32 spare bits lying around).
While I suppose
for (long i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++)
System.out.println(i);
has fewer characters, I can't really say that it is simpler. Shorter isn't necessarily simpler, it does have less code though.
I just have to add an answer...
public class PrintInts {
public static void main(String[] args) {
int i = Integer.MIN_VALUE;
do {
System.out.println(i);
++i;
} while (i != Integer.MIN_VALUE);
}
}
We don't want the body repeated (think of the maintenance!)
It doesn't loop forever.
It uses an appropriate type for the counter.
It doesn't require some wild third-party weirdo library.
Ah, and here I had just started writing
System.out.println(-2147483648);
System.out.println(-2147483647);
System.out.println(-2147483646);
Okay, just give me a few weeks to finish typing this up ...
The instructions didn't say I have to use a loop, and at least this method doesn't have any overflow problems.
Is there something tricky that I'm not catching? There probably is... (edit: yes, there is!)
class AllInts {
public static void main(String[] args) {
// wrong -- i <= Integer.MAX_VALUE will never be false, since
// incrementing Integer.MAX_VALUE overflows to Integer.MIN_VALUE.
for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++) {
System.out.println(i);
}
}
}
Since the printing is the bottleneck, a buffer would improve the speed quite a lot (I know because I just tried it):
class AllInts {
public static void main(String[] args) {
// a rather large cache; I did no calculations to optimize the cache
// size, but adding the first group of numbers will make the buffer
// as large as it will ever need to be.
StringBuilder buffer = new StringBuilder(10000000);
int counter = 0;
// note that termination check is now <
// this means Integer.MAX_VALUE won't be printed in the loop
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
buffer.append(i).append('\n');
if (++counter > 5000000) {
System.out.print(buffer);
buffer.delete(0, buffer.length()-1);
counter = 0;
}
}
// take care of the last value (also means we don't have to check
// if the buffer is empty before printing it)
buffer.append(Integer.MAX_VALUE);
System.out.println(buffer);
}
}
Also, this version will actually terminate (thanks to Daniel Lew for pointing out that there was, in fact, something tricky that I wasn't catching).
The total run time for this version (run with -Xmx512m) was 1:53. That's over 600000 numbers/second; not bad at all! But I suspect that it would have been slower if I hadn't run it minimized.
When I first looked at this, my first question was 'how do you define smallest and largest'. For what I thought was the most obvious definition ('smallest' == 'closest to 0') the answer would be
for (int i = 0; i >= 0; i++) {
System.out.println(i);
System.out.println(-i-1);
}
But everyone else seems to read 'smallest' as 'minimum' and 'largest' as 'maximum'
Come on folks, it said using java. It didn't say use an int in the for loop. :-)
public class Silly {
public static void main(String[] args) {
for (long x = Integer.MIN_VALUE; x <= Integer.MAX_VALUE; x++) {
System.out.println(x);
}
}
}
Another way to loop through every value using an int type.
public static void main(String[] args) {
int i = Integer.MIN_VALUE;
do {
System.out.println(i);
} while (i++ < Integer.MAX_VALUE);
}
Given the overview of the best answers, I realized that we're seriously lacking in the brute-force department. Jay's answer is nice, but it won't actually work. In the name of Science, I present - Bozo Range:
import java.util.Random;
import java.util.HashSet;
class Test {
public static void main(String[] args) {
Random rand = new Random();
HashSet<Integer> found = new HashSet<Integer>();
long range = Math.abs(Integer.MAX_VALUE - (long) Integer.MIN_VALUE);
while (found.size() < range) {
int n = rand.nextInt();
if (!found.contains(n)) {
found.add(n);
System.out.println(n);
}
}
}
}
Note that you'll need to set aside at least 4 GB of RAM in order to run this program. (Possibly 8 GB, if you're on a 64-bit machine, which you'll probably require to actually run this program...). This analysis doesn't count the bloat that the Integer class adds to any given int, either, nor the size of the HashSet itself.
The maximum value for int is Integer.MAX_VALUE and the minimum is Integer.MIN_VALUE. Use a loop to print all of them.
Package fj is from here.
import static fj.pre.Show.intShow;
import static fj.pre.Show.unlineShow;
import static fj.data.Stream.range;
import static java.lang.Integer.MIN_VALUE;
import static java.lang.Integer.MAX_VALUE;
public class ShowInts
{public static void main(final String[] args)
{unlineShow(intShow).println(range(MIN_VALUE, MAX_VALUE + 1L));}}
At 1000 lines/sec you'll be done in about 7 weeks. Should we get coffee now?
Just improving the StringBuilder's approach a little:
2 threads + 2 buffers (i.e. StringBuilder): The main idea is that one thread fills one buffer while the other thread dumps the content of the other buffer.
Obviously, the "dumper" thread will always run slower than the "filler" thread.
If the interviewer was looking for all the Integer values possible in Java, You might try giving him a solution using Long:
class AllIntegers{
public static void main(String[] args) {
for (int i = Integer.MIN_VALUE; i < Long.MAX_VALUE; i++) {
System.out.println(i);
}
System.out.println(Long.MAX_VALUE);
}
}
This should print a range from -9223372036854775808 to 9223372036854775807 which is way more than you would achieve using Integer.

Categories