I was learning dynamic programming's application to the Fibonacci Sequence and had a question. Here is the code for reference:
import java.math.BigInteger;
import java.util.Arrays;
public class FibonacciNumbersB {
static BigInteger[] dp = new BigInteger[10000];
public static void main(String[] args) {
Arrays.fill(dp, BigInteger.ZERO);
dp[0] = BigInteger.ONE;
dp[1] = BigInteger.ONE;
for(int i = 4; i < 9999; i++)
System.out.println(fibRecurse(i).toString());
}
public static BigInteger fibRecurse(int N) {
for(int i = 2; i < N; i++) {
// For numerous calls to this function, this will save as it goes
if(dp[i].equals(BigInteger.ZERO))
dp[i] = dp[i - 1].add(dp[i - 2]);
}
return dp[N - 1];
}
}
I have a statement check if dp[i] equals 0 in the fibRecurse method (although fibRecurse isn't recursive).
Is it more efficient to check if dp[i] has been calculated already or to just let dp[i] equal to the sum of the previous two elements?
I would prefer a Map<Integer, BigInteger> over using a fixed BigInteger[] when performing this memoization. Note that your current approach is not recursive. The Map might be declared and initialized like
static Map<Integer, BigInteger> memo = new HashMap<>();
static {
memo.put(0, BigInteger.ONE);
memo.put(1, BigInteger.ONE);
}
Then check if the current n is present in the memo (if it is, return it) - otherwise, computer and store it. Like,
public static BigInteger fibRecurse(int n) {
if (memo.containsKey(n)) {
return memo.get(n);
}
BigInteger v = fibRecurse(n - 1).add(fibRecurse(n - 2));
memo.put(n, v);
return v;
}
A version without memoization would simply omit memo like
public static BigInteger fibRecurseSlow(int n) {
if (n == 0 || n == 1) return BigInteger.ONE;
BigInteger v = fibRecurse(n - 1).add(fibRecurse(n - 2));
return v;
}
I think you can infer from the method names I've chosen which is slower.
import java.math.BigInteger;
import java.util.Arrays;
public class FibonacciNumbersB {
static BigInteger[] dp = new BigInteger[10000];
public static void main(String[] args) {
dp[0] = BigInteger.ONE;
dp[1] = BigInteger.ONE;
int N = 9999;
fibRecurse(N);
for(int i = 0; i < N; i++)
System.out.println(dp[i].toString()) ;
}
public static void fibRecurse(int N) {
for(int i = 2; i < N; i++) {
dp[i] = dp[i - 1].add(dp[i - 2]);
}
}
}
The code that is for finding fibonacci sequence can be write easily.Let's consider recursive code for finding fibonacci number set.
import java.util.Scanner;
class fac{
public static void main(String a[]){
Scanner sc=new Scanner(System.in);
System.out.print("Enter Your number :");
int n=sc.nextInt();
System.out.print(fibonacci(n));
}
public static int fibonacci(int x){
if(x<2){
return 1;
}
else{
return (fibonacci(x-1)+fibonacci(x-2));
}
}
}
In this stage, there are many same subproblems are calculating again and again.So in this case, time complexity goes to height for large input. Because of that reason , dynamic programming technique was came ...In dynamic programming ,an extra table('lookUp' table) is maintained for storing previous calculated subproblems' values. before calculating next subproblems' value, check whether availability of the answer for the particular subproblem in created table('lookUp' table).If it is in the 'lookUp table', get the answer for particular subproblem. If it is not in the 'lookUp ' table, calculate value of the particular problem and store the 'lookUp ' table. That is the meaning of the dynamic programming technique.There are two ways for performing this technique.
1.Memoization -
memoization is the technique that calculating values of subproblems Top- Down manner.Let's consider the code of fibonacci sequence.
import java.util.Scanner;
class fab{
public static void main(String a[]){
Scanner sc=new Scanner(System.in);
System.out.print("Enter Your number :");
int n=sc.nextInt();
int[] lookUp=new int[n];
int i;
for(i=0;i<n;i++){
lookUp[i]=-1;
}
fibonachi(n);
}
public static void fibonachi(int x){
if(lookUp[x]==-1){
if(x<=1){
lookUp[x]=x;
}
else{
lookUp[x]=fibonachi(x-1)+fibonachi(x-2);
}
}
System.out.print(lookUp[x]);
}
}
2.Tabulation - This calculation goes to Bottom to Top manner.At first consider the base case and perform . Then perform the next steps using previous cases.Les's consider fibonacci sequence code with tabulation technique.
import java.util.Scanner;
class fac{
public static void main(String a[]){
Scanner sc=new Scanner(System.in);
System.out.print("Enter Your number :");
int n=sc.nextInt();
int[] lookUp=new int[n];
int i;
lookUp[0]=1; // store base case values in the 'lookUp' table
lookUp[1]=1;
for(i=2;i<n;i++){
lookUp[i]=lookUp[i-1]+lookUp[i-2];
}
System.out.print(lookUp[n-1]);
}
}
In this case , base case values are stored at first.then calculates next values using previous ones..In tabulation all the values must be calculated because new value calculated using previous vlues..so memoization is better than tabulation.That's all. I hope, you could get idea.Thank you!
Related
I tried attempting this but I think I'm doing something wrong. I am a beginner level programmer and I really need help on this. I feel like I'm close to the answer but I'm not sure what's wrong with my program. I try checking my answer by square rooting the Variance result to get Standard Deviation but they don't match.
import java.util.Random;
public class Lab6 {
public static void main(String[] args) {
System.out.println("The Average Value is:"+avgValue());
System.out.println("The Standard Deviation is:"+stdDev());
System.out.println("The Variance is:"+Var());
}
public static int randomFill(){
Random rand = new Random();
int randomNum = rand.nextInt();
return randomNum;
}
private static int[] anArray;
public static int[] list() {
anArray = new int[100];
for(int i=0;i<anArray.length;i++)
{
anArray[i] = randomFill();
}
return anArray;
}
private static int sum;
public static int avgValue() {
int []a = list();
for (int e:a)
{
sum +=e;
}
int n=100;
sum=sum/n;
return sum;
}
private static int pwr;
public static int stdDev() {
int []b = list();
int dev=0;
for (int e:b)
{
dev=(e-sum)+dev;
}
pwr=(dev*dev)/99;
double root=Math.sqrt(pwr);
return pwr;
}
public static int Var() {
int c= pwr;
int opp=c*c;
return opp;
}
}
Its been a while since I did statistics but I can point out that your avgValue() method and your stdDev() are computing against two different int arrays. When you call list() you get a different array of integers each time and overwrite anArray.
I'd recommend creating the array inside your main method and then passing it as a parameter to the other methods. If you want to go the route you're on, change "int []b = list();" to "int []b = anArray;" and you should be fine.
Overall I think you might want to try looking into method parameters and variable scope next to improve your Java. Keep on truckin'; it gets easier.
I don't recall the variance and standard deviation formulas correctly, but one mistake related to programming logic in your code is that you have called list() once while calculating the average and once while calculating the standard deviation.
Every call to your list() method returns a new array with new random values. So, essentially, even if you calculate standard deviation correctly from the code, the average you consider (i.e the sum variable) corresponds to the average of some other array.
public static void main(String... args) {
int[] arr = createRandomArray(100);
System.out.printf(Locale.US, "The Average Value is: %.2f\n", mean(arr));
System.out.printf(Locale.US, "The Standard Deviation is: %.2f\n", standardDeviation(arr));
System.out.printf(Locale.US, "The Variance is: %.2f\n", variance(arr));
}
public static int[] createRandomArray(int total) {
int[] arr = new int[total];
Random random = new Random();
for (int i = 0; i < arr.length; i++)
arr[i] = random.nextInt(100);
return arr;
}
public static double mean(int[] arr) {
return (double)Arrays.stream(arr).sum() / arr.length;
}
public static double standardDeviation(int[] arr) {
double mean = mean(arr);
double sum = IntStream.range(0, arr.length)
.boxed()
.map(i -> Math.pow(arr[i] - mean, 2))
.mapToDouble(d -> d)
.sum();
return Math.sqrt(sum / arr.length);
}
public static double variance(int[] arr) {
return Math.pow(standardDeviation(arr), 2);
}
I need to use recursion to make an algorithm which finds the sum of x integers after an integer m. For example, if m is 2 and n is 5, I would need to find the sum of 2+3+4+5+6 using recursion.
The code I have so far would (for the example illustrated above) works in such way: 2+3+3+3+3. Any help at all is greatly appreciated as I have an exam tomorrow and questions like these may be included.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Input a value for n");
int n = input.nextInt();
System.out.println("Input a value for m");
int m = input.nextInt();
System.out.println(sho (m,n));
}
public static int sho (int m, int n){
int sum = 0;
if(n<=0){
return m;
}
sum = sho(m+1,n-1);
sum = sum +(m);
return sum;
}
You only need to implement the summation of a series using recursion. The starting and ending points are really just minor logic. The inductive case of the recursion is is that the current value is less than the end of the series. In this case, we return the current value plus a recursive call with the starting point increased by one. The base case occurs when we reach the end of the series. For the base case, we just return the max value and stop the recursion.
public static int sho(int curr, int max) {
if (curr == max) {
return curr;
}
else {
return curr + sho(curr + 1, max);
}
}
public static void main(String args[]) {
System.out.println(sho(10, 15)); // 10 11 12 13 14 15
}
One problem I see with your code is your recursion logic:
sum = sho(m+1, n-1);
I don't think that decreasing the upper bound is the way to go here. Instead, keep that bound fixed and advance through the series by making another recursive call. Decreasing the upper bound sounds like mixing recursion with an iterative approach.
Demo
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Input a value for n");
int n = input.nextInt();
System.out.println("Input a value for m");
int m = input.nextInt();
System.out.println(sho (m,n,0));
}
public static int sho (int m, int n,int sum){
if(n<=0){
return sum;
}
sum=sum+m;
sum = sho(m+1,n-1,sum);
return sum;
}
Try this
I need to find the smallest number which digit numbers product is equal to a given num.
import java.util.Scanner;
class timus_1014_2 {
public static void main(String[] args){
int[] arr = new int[10]; // eskan ban# chem imanum inchi a statik,
int prod = 1;
int j = 0;
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for (int i = 2; i < 10; ++i){
if (n % i == 0) {
arr[j] = i;
j++;
}
}
prod = prod * arr[j];
System.out.print(prod);
}
}
Something is wrong with the logic, whats is the problem when I input 10 it should give 25 but it gives 0. Please give ideas of how to make a program find a number which digits product is a given num.
If I understood your problem correctly you need a number whose product of digits equals a number N. Since you asked for new algorithm , you can chck following code.
Logic:
Note : For number whose prime factors are less than 10
Get all factors from 9 -> 2
add to list
print in reverse or use stack instead of list
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number");
int num = in.nextInt();
List<Integer> lst = new ArrayList<>();
for (int p = 9; p >= 2; p--) {
while (num % p == 0) {
num /= p;
lst.add(p);
}
}
String smallestNumber = "";
for (int i = lst.size() - 1; i >= 0; i--) {
smallestNumber = smallestNumber + lst.get(i);
}
System.out.println("Smallest number : " + smallestNumber);
}
}
Output :
Enter number
10
Smallest number : 25
Enter number
144
Smallest number : 289
Enter number
12
Smallest number : 26
I suggest you look at each error is fix it one by one. I also suggest you use an IDE which will show you the errors and you type and will help ensure you don't have an overwhelming number of errors and you can see if those error disappear based on your corrections.
BTW Often when you use an array for a short piece of code, it can often be eliminate as I suspect it can be removed in your case.
Static methods can not access non-static members of class.
In your case prod is member variable of class but not static. To fix the error , try to make prod as static.
private static int prod = 1;
I would prefer , to make it local variable if no other method is using it.
The problem here is you need to create an object of the particular class to call a particular method associated with it
import java.util.Scanner;
class DigPro {
static int[] arr = new int[10]; // eskan ban# chem imanum inchi a statik,
int prod = 1;
public static void main(String[] args){
Scanner in = new Scanner(System.in);
DigPro obj = new DigPro();
obj.prime(in.nextInt());
}
public void prime(int n){
for (int i = 1; i < 10; ++i){
for (int j = 0; j < 9; ++j) {
if (n % i == 0) {
arr[j] = i;
}
prod = prod * arr[j];
}
}
System.out.print(prod);
}
}
Here you need to create an object say obj of DigPro class and then call prime(int n) method with that object. Also your division is startint with zero which is changed to one
In above code you are increasing j after the assigning value to arr[j].You should do the following:-
prod = prod * arr[j-1];
Here it will multiply prod with last array updated. That is why you are getting zero. And for your another question find the smallest number which digit numbers product is equal to a given num has similar answer at this link.
Since this is actually a pretty interesting problem, I took the time to come up with a correct solution for all possible integer inputs.
import java.util.*;
public class Main{
public static void main(String[] args) {
System.out.println("Enter number:");
int number = new Scanner(System.in).nextInt();
Stack<String> factors = new Stack<>();
if(number==0){
factors.push("0");
}else if(number==1){
factors.push("1");
}else{
for(int f=9;f>1;f--){
while(number%f==0){
factors.push(Integer.toString(f));
number/=f;
}
}
}
if(number<0){
factors.push("-");
}
if(number>9){
System.out.println("This is impossible.");
}else{
System.out.println("Smallest Number:");
while(!factors.empty()) System.out.print(factors.pop());
}
}
}
I am trying to develop code for SPOJ factorial problem number 11. The following is my code
import java.math.*;
import java.io.*;
public class Problem11 {
/**
* Count the number of zeroes at the end of
* the factorial value of a number.
*/
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int numOfInputs=0;
numOfInputs=Integer.parseInt(br.readLine());
BigInteger nextNum[]=new BigInteger[numOfInputs];
BigInteger factValue[]=new BigInteger[numOfInputs];
//Get all the numbers to be computed
for(int count=0;count<numOfInputs;count++)
{
nextNum[count]=new BigInteger(br.readLine());
}
//Obtain the factorial value for each number
for(int count=0;count<numOfInputs;count++)
{
factValue[count]=getFact(nextNum[count]);
}
//Obtain the number of trailing zeroes
for(int count=0;count<numOfInputs;count++)
{
//System.out.println(factValue[count]);
System.out.println(getZeroes(factValue[count]));
}
}
public static String getZeroes(BigInteger num)
{
int numOfZeroes=0;
while(num.remainder(BigInteger.TEN).equals(BigInteger.ZERO))
{
num=num.divide(BigInteger.TEN);
numOfZeroes++;
}
return String.valueOf(numOfZeroes);
}
public static BigInteger getFact(BigInteger num)
{
BigInteger factorial=BigInteger.ONE;
if(num.equals(0))
{
return (BigInteger.valueOf(1));
}
else
{
int count=1;
while((BigInteger.valueOf(count).compareTo(num))<=0)
{
factorial=factorial.multiply(BigInteger.valueOf(count));
count++;
}
}
return factorial;
}
}
The code works fine for numbers up to 5 digits with small delay and for the last number
8735373 it is taking too much time, if I submit my solution, the judge shows compilation error.. I am unable to figure out whats the error. Please have a look at my code and help me to trace the problem.
You might look at this method for finding the number of trailing zeros in n!.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = in.nextInt();
for (int i = 0; i < count; i++) {
int n = in.nextInt();
int result = 0;
for (int d = 5; d <= n; d *= 5) {
result += n / d;
}
System.out.println(result);
}
}
}
Your approach (naive: counting the real factorial value and then counting the zeros manually) would NEVER pass no matter how. Take a look at the extreme case (i.e. upper limit of the factorial, I don't even think the given memory limit is enough to compute it). Look at the problem from different way, think what the real problem is, that's the art of problem solving ;)
Hint: what can produce and add more 0s to the end of a number, specifically by multiplication?
The reason for your error is it should be public class Main
Also your code will get TLE, you must observe that brute force will never work on SPOJ. The way to solve this is to see an interesting pattern with powers of 5 and the number of zeroes at the end.
Here is a solution in C. We don't need to compute the exact factorial for this problem.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 1000000
int xpn(int x, int n){
int prod=1;
while(n){
prod*=x;
n--;
}
return prod;
}
int trail(int x){
int numZero=0;
int i=1;
int k;
for(;x/xpn(5,i);i++){
numZero+=(x/xpn(5,i));
}
return numZero;
}
int main(int argc, char **argv){
#if 1
int n;
int num[MAX];
int zero[MAX];
scanf("%d",&n);
int count=n;
int i=0;
while(count){
scanf("%d",&num[i]);
zero[i]=trail(num[i]);
printf("%d\n",zero[i]);
i++;
count--;
}
#endif
return 0;
}
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
Scanner s = new Scanner(System.in);
int t = s.nextInt();
while (t-->0){
int n = s.nextInt();
int count = 0;
while(n>0){
count +=n/5;
n/=5;
}
System.out.println(count);
}
}
}
This solution will work absolutely fine.
Let me explain it.
When you refer to quantitative aptitude there is a short formula for calculating the number of trailing zeroes for any factorial number. Divide the number directly by 5 and start adding quotient and then divide quotient with 5 and again add until the value start giving constant quotient. Refer to below example. If you don't even understand refer to quantitative aptitude from any source.
e.g.
1. 60! 60/5 = 12, 12/5 = 2, add all the quotient i.e equals to 14.
2. 500! 500/5 = 100, 100/5 = 20, 20/5 = 4, ans = 124.
I decided to implement a very simple program recursively, to see how well Java handles recursion*, and came up a bit short. This is what I ended up writing:
public class largestInIntArray {
public static void main(String[] args)
{
// These three lines just set up an array of ints:
int[] ints = new int[100];
java.util.Random r = new java.util.Random();
for(int i = 0; i < 100; i++) ints[i] = r.nextInt();
System.out.print("Normal:"+normal(ints,-1)+" Recursive:"+recursive(ints,-1));
}
private static int normal(int[] input, int largest) {
for(int i : input)
if(i > largest) largest = i;
return largest;
}
private static int recursive(int[] ints, int largest) {
if(ints.length == 1)
return ints[0] > largest ? ints[0] : largest;
int[] newints = new int[ints.length - 1];
System.arraycopy(ints, 1, newints, 0, ints.length - 1);
return recursive(newints, ints[0] > largest ? ints[0] : largest);
}
}
And that works fine, but as it's a bit ugly I wondered if there was a better way. If anyone has any thoughts/alternatives/syntactic sugar to share, that'd be much appreciated!
P.s. If you say "use Lisp" you win nothing (but respect). I want to know if this can be made to look nice in Java.
*and how well I handle recursion
Here's how I might make the recursive method look nicer:
private static int recursive(int[] ints, int largest, int start) {
if (start == ints.length) {
return largest;
}
return recursive(ints, Math.max(ints[start], largest), start + 1);
}
This avoids the expensive array copy, and works for an empty input array. You may implement an additional overloaded method with only two parameters for the same signature as the iterative function:
private static int recursive(int[] ints, int largest) {
return recursive(ints, largest, 0);
}
2 improvements:
no copy of the array (just using the offset)
no need to give the current max
private static int recursive(int[] ints, int offset) {
if (ints.length - 1 == offset) {
return ints[offset];
} else {
return Math.max(ints[offset], recursive(ints, offset + 1));
}
}
Start the recursion with recursive(ints, 0).
You could pass the current index as a parameter rather than copying almost the entire array each time or you could use a divide and conquer approach.
public static int max(int[] numbers) {
int size = numbers.length;
return max(numbers, size-1, numbers[size-1]);
}
public static int max(int[] numbers, int index, int largest) {
largest = Math.max(largest, numbers[index]);
return index > 0 ? max(numbers, index-1, largest) : largest;
}
... to see how well Java handles recursion
The simple answer is that Java doesn't handle recursion well. Specifically, Sun java compilers and Hotspot JVMs do not implement tail call recursion optimization, so recursion intensive algorithms can easily consume a lot of stack space.
However, I have seen articles that say that IBM's JVMs do support this optimization. And I saw an email from some non-Sun guy who said he was adding it as an experimental Hotspot extension as a thesis project.
Here's a slight variation showing how Linked Lists are often a little nicer for recursion, where "nicer" means "less parameters in method signature"
private static int recursive(LinkedList<Integer> list) {
if (list.size() == 1){
return list.removeFirst();
}
return Math.max(list.removeFirst(),recursive(list));
}
Your recursive code uses System.arrayCopy, but your iterative code doesn't do this, so your microbenchmark isn't going to be accurate. As others have mentioned, you can clean up that code by using Math.min and using an array index instead of the queue-like approach you had.
public class Maximum
{
/**
* Just adapted the iterative approach of finding maximum and formed a recursive function
*/
public static int max(int[] arr,int n,int m)
{
if(m < arr[n])
{
m = arr[n];
return max(arr,n - 1,m);
}
return m;
}
public static void main(String[] args)
{
int[] arr = {1,2,3,4,5,10,203,2,244,245,1000,55000,2223};
int max1 = max(arr,arr.length-1,arr[0]);
System.out.println("Max: "+ max1);
}
}
I actually have a pre made class that I setup for finding the largest integer of any set of values. You can put this class into your project and simply use it in any class like so:
System.out.println(figures.getLargest(8,6,12,9,120));
This would return the value "120" and place it in the output. Here is the methods source code if you are interested in using it:
public class figures {
public static int getLargest(int...f) {
int[] score = new int[f.length];
int largest=0;
for(int x=0;x<f.length;x++) {
for(int z=0;z<f.length;z++) {
if(f[x]>=f[z]) {
score[x]++;
}else if(f[x]<f[z]) {
}else {
continue;
}
if(z>=f.length) {
z=0;
break;
}
}
}
for(int fg=0;fg<f.length;fg++) {
if(score[fg]==f.length) {
largest = f[fg];
}
}
return largest;
}
}
The following is a sample code given by my Java instructor, Professor Penn Wu, in one of his lectures. Hope it helps.
import java.util.Random;
public class Recursion
{
static int s = 0;
public static Double max(Double[] d, int n, Double max)
{
if (n==0) { return max;}
else
{
if (d[n] > max)
{
max = d[n];
}
return max(d, n-1, max);
}
}
public static void main(String[] args)
{
Random rn = new Random();
Double[] d = new Double[15];
for (int i=0; i
{
d[i] = rn.nextDouble();
System.out.println(d[i]);
}
System.out.print("\nMax: " + max(d, d.length-1, d[0]));
}
}
Here is my alternative
public class recursion
{
public static int max( int[] n, int index )
{
if(index == n.length-1) // If it's simple, solve it immediately:
return n[index]; // when there's only one number, return it
if(max(n, index+1) > n [index]) // is one number bigger than n?
return max(n, index+1); // return the rest, which contains that bigger number
return n[index]; // if not, return n which must be the biggest number then
}
public static void main(String[] args)
{
int[] n = {100, 3, 5, 1, 2, 10, 2, 15, -1, 20, -1203}; // just some numbers for testing
System.out.println(max(n,0));
}
}