so I'm not really sure what to do what I've already done
/*
* a collection of methods to be completed
* complete each TODO body-code for the given methods
* use recursion for the first method and last method
*/
public class Methods
/*
* method to compute value of f(n) where:
* f(1) = 1
* f(n) = n + f(n-1) for n>1, n is even
* f(n) = n * f(n-1) for n>1, n is odd
*/
public static int f(int n) {
//TODO
return 0; //dummy line, replace this
}
/*
* method to compute the sum of the proper divisors of a given positive integer, n
* e.g., if n is 12, the sum of the proper divisors is:
* 1 + 2 + 3 + 4 + 6 = 16
* note: proper divisors are all divisors of an integer other than itself
*/
public static int sumOfDivisors(int n) {
//TODO
return 0; //dummy line, replace this
}
/*
* method that returns a String indicating whether a given positive integer, n, is:
* "abundant" - sum of proper divisors is greater than n
* "deficient" - sum of proper divisors is less than n
* "perfect" - sum of proper divisors is equal to n
*/
public static String numberType(int n) {
//TODO
return "foo"; //dummy line, replace this
}
/*
* method that returns the sum of the digits of the positive integer, n
* e.g., if n = 5403, the method will return:
* 5+4+0+3 = 12
* note: the right-most (1's) digit can be found using n%10
* the remaining digits (all but the 1's digit) can be found using n/10
*/
public static int sumOfDigits(int n) {
//TODO
return 0; //dummy line, replace this
}
//a dummy main method, not used
public static void main(String[] args) {
System.out.println("This program is not meant to be run on its own.");
System.out.println("This is just a dummy main method.");
}
} //end Methods
so yea any help would be great.
so I'm not really sure what to do what I've already done
You actually wrote only method declarations.
Your task is really well documented, you may try out to implement the utilities(like a public int[] divisors(int n) and so on) and eventually come back here and ask help about your concerns, posting either code or errors.
PS:This seems an academic assignment , have you checked some books, or notes?
Related
This code prints all prime numbers between start and end, based on the user's input.
What is its complexity? Is it O(end * sqrt(n))?
/**
* Print prime numbers between start and end inputs
* Time-Complexity: O(end * sqrt(n))
* Space-Complexity: O(1) only one value as input
* #param start, end
* #return
*/
public void printPrimeSeries(int start, int end) {
for (int i = start; i < end; i++) {
if (findPrimeOrNot(i)) {
System.out.println("The value " + i + " is a prime number");
}
}
}
public boolean findPrimeOrNot(int n) {
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter start number for prime:");
int startInput = scanner.nextInt();
System.out.println("Enter end number for prime:");
int endInput = scanner.nextInt();
PrimeNoSeries primeNoSeries = new PrimeNoSeries();
primeNoSeries.printPrimeSeries(startInput, endInput);
}
Going step by step, to be concise, let's call your start value m, and end as n:
printPrimeSeries method is linearly corelated to n - m
For each element within the range above, the complexity of inner loop is sqrt(n) - 2. Neglecting the constant it is sqrt(n)
So, the complexity appears to be O((n - m) * sqrt(n)).
The overall complexity is O(end - start) * sqrt(end)). FYI: I show you an alternative estimation, which is not as tight:
In O-notation you are interested in the worst case, therefore we can assume that start is always 0. Now we only need end for the analysis.
The method printPrimeSeries is just O(end), from 0 to end. The method uses findPrimeOrNot that iterates from 2 to Math.sqrt(n), which is O(sqrt(n)). The maximum value for n is the value of end, so we can call the complexity O(sqrt(end)) for our purposes. Combining both is O(end) * O(sqrt(end)), which is just O(end sqrt(end)).
There are interesting details to the question, which have to do with the distribution of prime numbers. You can read about it here.
I found a formula in the Internet for calculating the trapezoid method , it works as it should, but I do not see why should I performed the following lines in the trapez method:
sum = 0.5 * bef + (h * sum);
i= i+ 2
The first iteration performed by the following command in main :
tra[0] = 0.5 * ((b - a) / n) * (function(a) + function(b));
//calculates the first step value
the trapez method for the next iterations:
/**
* calculate the next step with trapez method
* #param a -lower limit
* #param b -upper limit
* #param bef -previous step value
* #param n -number of dividing points
* #return integral area
*/
public static double trapz(double a, double b,double bef, int n)
{
double sum = 0;
double h = ((b - a)/n);
for (int i = 1; i <= n; i = i + 2) {
sum += function(a + (i) * h);
}
sum = 0.5 * bef + (h * sum);
return sum;
}
The function would be used in conjunction with a driver loop that doubles the number of subintervals at each iteration, refining the estimated integral until the difference from one iteration to the next is less than some threshold criterion. It is desirable in such an endeavor to avoid repeating computations that have already been performed, and that's the point of the lines you asked about.
Consider the function values that are needed when applying the trapezoid rule on a given number of subintervals. Now consider the function values needed for splitting each subinterval in half and applying the trapezoid rule to those subintervals. Half (give or take 1) of the function values needed in the latter case are the same ones needed in the former. The code presented simply reuses the previously computed values (0.5 * bef), adding to them only the new values (i = i + 2). It must scale down the previous estimate by a factor of two to account for splitting the subintervals in two.
Note that for the code to be right, it appears that argument n must represent the number of subintervals of the integration region, not the number of dividing points as its documentation claims.
"public static int readInt(String s)" wat does this exactly do in a program?? Currently i need to use 4 of these but they all different and for the one i showed up here, i need to make a program where the user is prompted something and if the input is an int then it gets displayed and then goes to the second input for the user and if right then goes, but else if not an int; if its a double then print out "This is not valid..." and then will repeat the first one again and will also do the same thing for the second input if the second one prompted by the user is not an integer. There will be a total of two inputs for the user. What should i do to make a program for this? I am confused of how to use this "public static int readInt(String s)".
package rationalnumber;
import java.util.*;
public class Utility
{
public static int readInt(String s)
{
}
public static double readDouble(String s)
/**
* Generates a random integer between min and max, inclusive
* Precondition: min <= max
* #param min lower bound for the random integer
* #param max upper bound for the random integer
* #return A random integer
*/
public static int randomInt(int min, int max)
{
}
/**
* Computes the gcd between 2 nonnegative integers
* Precondition: num1 >= 0, num2 >= 0
* #param num1 The first integer
* #param num2 The second integer
* #return the gcd of num1 and num 2, gcd is 1 if both are 0,
* gcd is the non-zero number if only one is 0.
*/
public static int gcd(int num1, int num2)
{
}
this is like part of the code....i also need to add comments on here well so far those are the last two parts of my code but i couldnt start it without the first two parts.
package rationalnumber;
/**
* Test program for the Utility class
*/
public class UtilityTest
{
public static void main(String[] args)
{
String prompt1 = "Enter first integer: ";
String prompt2 = "Enter second integer: ";
int a = Utility.readInt(prompt1);
int b = Utility.readInt(prompt2);
int small = Math.min(a, b);
int large = Math.max(a, b);
System.out.println("A few random integers: ");
System.out.println(Utility.randomInt(small, large));
System.out.println(Utility.randomInt(small, large));
System.out.println(Utility.randomInt(small, large));
System.out.println(Utility.randomInt(small, large));
System.out.printf("The gcd of %d and %d is ", a, b);
System.out.println(Utility.gcd(Math.abs(a), Math.abs(b)));
}
}
in the end i use this which is in the same program but in another folder to run it.
Break it down:
Public -- Signifies this is a public method
int -- Signifies that the function will return an integer
readInt -- Name of the function
String s -- Signifies that the function takes a parameter of type String that will be referred to as s within the function.
Public --a public method
int -- return tpye integer
readInt -- Name of the function that will read a string and return it as an integer.in your program it will read prompt1 and prompt2 , like take input form the user , and store them int a and int b.
String s -- Signifies that the function takes a parameter of type String that will be referred to as s within the function.
I need the count the number of decimal digits of a BigInteger. For example:
99 returns 2
1234 returns 4
9999 returns 4
12345678901234567890 returns 20
I need to do this for a BigInteger with 184948 decimal digits and more. How can I do this fast and scalable?
The convert-to-String approach is slow:
public String getWritableNumber(BigInteger number) {
// Takes over 30 seconds for 184948 decimal digits
return "10^" + (number.toString().length() - 1);
}
This loop-devide-by-ten approach is even slower:
public String getWritableNumber(BigInteger number) {
int digitSize = 0;
while (!number.equals(BigInteger.ZERO)) {
number = number.divide(BigInteger.TEN);
digitSize++;
}
return "10^" + (digitSize - 1);
}
Are there any faster methods?
Here's a fast method based on Dariusz's answer:
public static int getDigitCount(BigInteger number) {
double factor = Math.log(2) / Math.log(10);
int digitCount = (int) (factor * number.bitLength() + 1);
if (BigInteger.TEN.pow(digitCount - 1).compareTo(number) > 0) {
return digitCount - 1;
}
return digitCount;
}
The following code tests the numbers 1, 9, 10, 99, 100, 999, 1000, etc. all the way to ten-thousand digits:
public static void test() {
for (int i = 0; i < 10000; i++) {
BigInteger n = BigInteger.TEN.pow(i);
if (getDigitCount(n.subtract(BigInteger.ONE)) != i || getDigitCount(n) != i + 1) {
System.out.println("Failure: " + i);
}
}
System.out.println("Done");
}
This can check a BigInteger with 184,948 decimal digits and more in well under a second.
This looks like it is working. I haven't run exhaustive tests yet, n'or have I run any time tests but it seems to have a reasonable run time.
public class Test {
/**
* Optimised for huge numbers.
*
* http://en.wikipedia.org/wiki/Logarithm#Change_of_base
*
* States that log[b](x) = log[k](x)/log[k](b)
*
* We can get log[2](x) as the bitCount of the number so what we need is
* essentially bitCount/log[2](10). Sadly that will lead to inaccuracies so
* here I will attempt an iterative process that should achieve accuracy.
*
* log[2](10) = 3.32192809488736234787 so if I divide by 10^(bitCount/4) we
* should not go too far. In fact repeating that process while adding (bitCount/4)
* to the running count of the digits will end up with an accurate figure
* given some twiddling at the end.
*
* So here's the scheme:
*
* While there are more than 4 bits in the number
* Divide by 10^(bits/4)
* Increase digit count by (bits/4)
*
* Fiddle around to accommodate the remaining digit - if there is one.
*
* Essentially - each time around the loop we remove a number of decimal
* digits (by dividing by 10^n) keeping a count of how many we've removed.
*
* The number of digits we remove is estimated from the number of bits in the
* number (i.e. log[2](x) / 4). The perfect figure for the reduction would be
* log[2](x) / 3.3219... so dividing by 4 is a good under-estimate. We
* don't go too far but it does mean we have to repeat it just a few times.
*/
private int log10(BigInteger huge) {
int digits = 0;
int bits = huge.bitLength();
// Serious reductions.
while (bits > 4) {
// 4 > log[2](10) so we should not reduce it too far.
int reduce = bits / 4;
// Divide by 10^reduce
huge = huge.divide(BigInteger.TEN.pow(reduce));
// Removed that many decimal digits.
digits += reduce;
// Recalculate bitLength
bits = huge.bitLength();
}
// Now 4 bits or less - add 1 if necessary.
if ( huge.intValue() > 9 ) {
digits += 1;
}
return digits;
}
// Random tests.
Random rnd = new Random();
// Limit the bit length.
int maxBits = BigInteger.TEN.pow(200000).bitLength();
public void test() {
// 100 tests.
for (int i = 1; i <= 100; i++) {
BigInteger huge = new BigInteger((int)(Math.random() * maxBits), rnd);
// Note start time.
long start = System.currentTimeMillis();
// Do my method.
int myLength = log10(huge);
// Record my result.
System.out.println("Digits: " + myLength+ " Took: " + (System.currentTimeMillis() - start));
// Check the result.
int trueLength = huge.toString().length() - 1;
if (trueLength != myLength) {
System.out.println("WRONG!! " + (myLength - trueLength));
}
}
}
public static void main(String args[]) {
new Test().test();
}
}
Took about 3 seconds on my Celeron M laptop so it should hit sub 2 seconds on some decent kit.
I think that you could use bitLength() to get a log2 value, then change the base to 10.
The result may be wrong, however, by one digit, so this is just an approximation.
However, if that's acceptable, you could always add 1 to the result and bound it to be at most. Or, subtract 1, and get at least.
You can first convert the BigInteger to a BigDecimal and then use this answer to compute the number of digits. This seems more efficient than using BigInteger.toString() as that would allocate memory for String representation.
private static int numberOfDigits(BigInteger value) {
return significantDigits(new BigDecimal(value));
}
private static int significantDigits(BigDecimal value) {
return value.scale() < 0
? value.precision() - value.scale()
: value.precision();
}
This is an another way to do it faster than Convert-to-String method. Not the best run time, but still reasonable 0.65 seconds versus 2.46 seconds with Convert-to-String method (at 180000 digits).
This method computes the integer part of the base-10 logarithm from the given value. However, instead of using loop-divide, it uses a technique similar to Exponentiation by Squaring.
Here is a crude implementation that achieves the runtime mentioned earlier:
public static BigInteger log(BigInteger base,BigInteger num)
{
/* The technique tries to get the products among the squares of base
* close to the actual value as much as possible without exceeding it.
* */
BigInteger resultSet = BigInteger.ZERO;
BigInteger actMult = BigInteger.ONE;
BigInteger lastMult = BigInteger.ONE;
BigInteger actor = base;
BigInteger incrementor = BigInteger.ONE;
while(actMult.multiply(base).compareTo(num)<1)
{
int count = 0;
while(actMult.multiply(actor).compareTo(num)<1)
{
lastMult = actor; //Keep the old squares
actor = actor.multiply(actor); //Square the base repeatedly until the value exceeds
if(count>0) incrementor = incrementor.multiply(BigInteger.valueOf(2));
//Update the current exponent of the base
count++;
}
if(count == 0) break;
/* If there is no way to multiply the "actMult"
* with squares of the base (including the base itself)
* without keeping it below the actual value,
* it is the end of the computation
*/
actMult = actMult.multiply(lastMult);
resultSet = resultSet.add(incrementor);
/* Update the product and the exponent
* */
actor = base;
incrementor = BigInteger.ONE;
//Reset the values for another iteration
}
return resultSet;
}
public static int digits(BigInteger num)
{
if(num.equals(BigInteger.ZERO)) return 1;
if(num.compareTo(BigInteger.ZERO)<0) num = num.multiply(BigInteger.valueOf(-1));
return log(BigInteger.valueOf(10),num).intValue()+1;
}
Hope this will helps.
I am trying to solve Project Euler problem 2 in Java:
public class Euler2 {
public static long GenerateFibonacci(int term) {
long sum = 0;
long fib = 0;
long f1 = 0;
long f2 = 1;
if (term <=1) return term;
for (int i = 1; i <= term; i++) {
fib = f1 + f2;
f1 = f2;
f2 = fib;
if(fib %2 ==0)
sum += fib;
}
return sum;
}
/**
* #param args
*/
public static void main(String[] args) {
int n = 100;
long result = GenerateFibonacci(n);
System.out.println("The sum of the even Fibonacci numbers is: "+result);
}
}
When n is small I get the right answer but for bigger values I get the wrong result. What's the problem here?
int is limited to 32-bit accuracy, long to 64-bit.
When you exceed the limit by adding numbers whose result is larger then the bit limit, they "roll over" and you lose the most significant bits from the result of the addition - essentially, they are "rounded" to 32/64 bits.
Here's an example of rolling over:
int i = Integer.MAX_VALUE; // 2147483647
i++; // -2147483648
Roughly speaking, each fibonnacci number is double the previous one, so roughly speaking you can only handle in the order of 64 iterations using a long as the total.
The largest long value in Java is 9223372036854775807. Adding 1 to this value produces -9223372036854775807 because the integer values in most programming languages come from a finite set of values, and when you reach the highest value and add one the sequence "wraps around" to the beginning.
If you need to go outside this range, which you will to get the 100th Fibonacci number, use BigInteger.
The sum is greater than Long.MAX_VALUE. You're correct (in your comment to #Bohemian) that n is less than that limit, but it is rather surprising how quickly this simple series can grow. The 100th Fibonacci number, for example, is 354224848179261915075. The sum of the first 100 is a 20 digit number, just to give you a feeling for the scale you're dealing with.
You need to use BigInteger, you can also use the fact that every third Fibonacci number is even.
public static BigInteger sumOfEvenFibonacci(int term) {
BigInteger sum = BigInteger.ZERO;
BigInteger f1 = BigInteger.ONE;
BigInteger f2 = BigInteger.ONE;
for (int i = 1; i <= term; i+=3) {
BigInteger fib = f1.add(f2);
sum = sum.add(fib);
f1 = f2.add(fib);
f2 = fib.add(f1);
}
return sum;
}
System.out.println(sumOfEvenFibonacci(100));
prints
1213946614199987541226
You can improve efficiency of 'GenerateFibonacci' with following code. This should be a comment but I can not format the code in comment, I am doing this in answer,
public class FibUtil {
//Constants used in equation to calculate nth fib term
private static final double fibA=1/Math.sqrt(5);
private static final double fibB=(1+Math.sqrt(5))/2;
private static final double fibC=(1-Math.sqrt(5))/2;
public static double getNthFibTerm(long n){
return fibA*(Math.pow(fibB, n)-Math.pow(fibC, n));
}
}
Further, based on euler 2 problem statement, you can just add only nth terms which are multiples of 3. I leave 'why' to you.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package evenfibonaccisum;
import java.math.BigInteger;
/**
*
* #author blades of Aragon
*/
public class EvenFibonacciSum {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
long a=0;
long b=1;
long fib=1;
int i=10;
long sum=0;
while(fib<=4000000){
fib=a+b;
a=b;
b=fib;
if(fib>=4000000){
break ;
}
else{
if(fib%2==0){
sum=sum+fib;
}
}
}
System.out.println("sum of even Fibonacci "+sum);
}
}