My goal is to write a method showing how the fibonacci sequence moves. I have to use an array and equation to show how the numbers move on the array (thus iterating the value using fibonacci method: previous number + current number = next number).
This is the logic that I want to use with array[] as representation:
n = fibonacci number
i = 1;
previousNumber = 0
nextNumber = 1
sum = previousNumber + nextNumber;
while (i <= n) {
sum = previousNumber + nextNumber;
previousNumber = nextNumber;
nextNumber = sum;
return nextNumber;
I went this far and I am stuck:
long fibonacci(int fibonacci) {
int[] fib = new int[20];
if (fibonacci < 0) {
throw new IllegalArgumentException("n value cannot be negative number");
}
if (fibonacci == 0 || fibonacci == 1) {
return 1;
}
fib[0] = 1;
fib[1] = 1;
int i ;
for (i = 2; i < fibonacci; i++) {
fib[i] = fib[0] + fib[1];
fib[0] = fib[1];
fib[1] = fib[i];
}
return fib[i];
}
The returned value seems ok. In the fibonacci test, fib from 5 is 5 and 4 is 3. What worries me is how this string looks on the debugger. The way I move them makes them look like this : {3,5,2,3,5} and it should be {1,1,2,3,5}.
You don't need an array.
long fibonacci(int fibonacci) {
if (fibonacci < 0) {
throw new IllegalArgumentException("n value cannot be negative number");
}
if (fibonacci == 0 || fibonacci == 1) {
return 1;
}
first = 1;
second = 1;
sum i;
for (i = 2; i <= fibonacci; i++) {
sum = first + second;
first = second;
second = sum;
}
return sum;
}
This implementation is simpler and more readable.
Your loop is wrong. It should be:
for (i = 2; i <= fibonacci; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
return fib[i-1];
You should never change fib[0] and fib[1], and fib[i] should be the sum of the previous two elements.
If the goal was to calculate fib(i) without an array, you would need two variables to keep track of the last two values:
long fibonacci(int fibonacci) {
if (fibonacci < 0) {
throw new IllegalArgumentException("n value cannot be negative number");
}
if (fibonacci == 0 || fibonacci == 1) {
return 1;
}
int beforeLast = 1;
int last = 1;
int i;
int fib = 1;
for (i = 2; i <= fibonacci; i++) {
fib = last + beforeLast;
beforeLast = last;
last = fib;
}
return fib;
}
Here is how your method should look like:
static long fibonacci(int fibonacci) {
int[] fib = new int[20];
if (fibonacci < 0) {
throw new IllegalArgumentException("n value cannot be negative number");
}
if (fibonacci == 0 || fibonacci == 1) {
return 1;
}
fib[0] = 1;
fib[1] = 1;
int i;
for (i = 2; i < fibonacci; i++) {
fib[i] = fib[i - 1] + fib[i - 2]; // change here
}
return fib[i-1]; // change here
}
Related
I have an assignment where i get an number input from the user, for example : "57779227"
and i need to return the longest sequence of identical numbers. For this example, the longest sequence is "777" and the return should be 3 (as the amount of times the number "7" is in a row.
So far I wrote an iteration method.
***No loops to be used in this method, ONLY RECURSION. ***
Iteration example :
public static int maxSequence(int num) {
int max = 1; //initiate
int currentCount = 1;
int prevDigit = 11;//Because num%10 != 11 Always!
int currentDigit;
while (num!=0) {
currentDigit = num%10;
if (prevDigit == currentDigit)
currentCount++;
else if (currentCount > max)
max = currentCount;
if (prevDigit != currentDigit) //initiate for the next Iteration
currentCount = 1;
prevDigit = currentDigit;
num = num/10;
}
return max;
}
When previousDigit != currentDigit then a new count will be start
public static int maxSequence(int num) {
int previousMax = 1;
int currentMax = 1;
int previousDigit = num % 10;
num /= 10;
while (num != 0) {
int currentDigit = num % 10;
if (previousDigit == currentDigit) {
currentMax++;
} else {
if (previousMax < currentMax) {
previousMax = currentMax;
}
currentMax = 1;
previousDigit = currentDigit;
}
num /= 10;
}
return Math.max(currentMax, previousMax);
}
I wanted to use a for and a while loop to obtain the prime factors of a number. My while loop example works fine which I have posted below my for loop example. However, my for loop does not work, and i am guessing that I can't use a continue in the same manner that I used it in the while loop. If this is true, then how would I accomplish this. I have not been able to find a basic beginners example of this using a for loop. Thanks
// My getting largest prime factor using a for loop
public class LargestPrime{
public static void main(String[] args) {
int number = 36;
int largestPrime = 0;
for ( int i = 2; i <= number; i++){
if (number % i == 0){
largestPrime = i;
number /= i;
continue;
}
System.out.println(" largest prime = " + i);
}
}
}
//*******************************************************************
//*******************************************************************
public class LargestPrime {
// gettting largest prime using a while loop
public static int getLargestPrime(int number) {
if (number <= 1) {
return -1;
}
int largestPrime = 0;
int count = 2;
while (count <= number) {
if (number % count == 0) {
largestPrime = count;
number = number / count;
continue;
}
count++;
}
return largestPrime;
}
}
The problem is that continue in a for loop executes the update part (i++), which your while loop didn't.
The other problem is that you're printing inside the loop.
There are multiple way to fix this:
Do i-- before continue, so it evens out to nothing with the i++. This is a fairly common way to handle this.
Since you don't have any code after the if statement, you don't need the continue.
for (int i = 2; i <= number; i++) {
if (number % i == 0) {
largestPrime = i;
number /= i;
i--; // to retry same `i` value
}
}
Do the i++ "yourself", i.e. not as part of for loop:
for (int i = 2; i <= number; ) {
if (number % i == 0) {
largestPrime = i;
number /= i;
continue;
}
i++;
}
Or:
for (int i = 2; i <= number; ) {
if (number % i == 0) {
largestPrime = i;
number /= i;
} else {
i++;
}
}
Use a while loop inside the for loop:
for (int i = 2; i <= number; i++) {
while (number % i == 0) {
largestPrime = i;
number /= i;
}
}
That can be shortened to:
for (int i = 2; i <= number; i++)
for (; number % i == 0; number /= i)
largestPrime = i;
Though rather than assign largestPrime repeatedly, you could do this:
for (int i = 2; i <= number; i++) {
if (number % i == 0) {
largestPrime = i;
do {
number /= i;
} while (number % i == 0);
}
}
I can't figure out why, but when the power function is used, it adds a (what seems to be random) integer into the middle of the answer. I can't figure out why, can any of you see anything unusual? Thanks
//multiplication method
public IntValue Multiply(IntValue multiplier) {
StringBuilder product = new StringBuilder();
int pos = 0;
for (int i = multiplier.getValue().length() - 1; i >= 0; i--) {
int currentPosition = pos++;
int carry = 0;
int multiplierDigit = Character.getNumericValue(multiplier.getValue().charAt(i));
for (int j = value.length() - 1; j >= 0; j--) {
int multiplicandDigit = Character.getNumericValue(value.charAt(j));
int tempProduct = currentPosition < product.length()
? Character.getNumericValue(product.charAt(currentPosition)) : 0;
int currentProduct = (multiplicandDigit * multiplierDigit) + carry + tempProduct;
if (currentProduct > 9) {
carry = currentProduct / 10;
currentProduct = currentProduct % 10;
}
if (currentPosition < product.length()) {
product.setCharAt(currentPosition, Character.forDigit(currentProduct, 10));
} else {
product.append(currentProduct);
}
++currentPosition;
}
if (carry > 0) {
if (currentPosition < product.length()) {
product.setCharAt(currentPosition, Character.forDigit(carry, 10));
} else {
product.append(carry);
}
}
}
return new IntValue(product.reverse().toString());
}
//number1 and number2 are IntValues.
//power method
public IntValue Power(long n) {
IntValue result = new IntValue("1");
for(int i = 0; i < n; i++) {
result = result.Multiply(this);
}
return result;
}
System.out.println("Result = "+number1.Power(Long.parseLong(number2.toString())));
Try the following code:
BigInteger number1 = new BigInteger("5");
System.out.println("Result = " + number1.pow(5).toString());
It's how we do it in java.
There is a library for working with powers in Java, namely Math.pow (for small numbers) and BigInteger pow (for arbitrary large numbers). Note that BigInteger power cannot compute fractional powers.
There are iterative DIY algorithms for fractional powers as well, for example
BigInteger sqrt(BigInteger n) {
BigInteger a = BigInteger.ONE;
BigInteger b = new BigInteger(n.shiftRight(5).add(new BigInteger("8")).toString());
while(b.compareTo(a) >= 0) {
BigInteger mid = new BigInteger(a.add(b).shiftRight(1).toString());
if(mid.multiply(mid).compareTo(n) > 0) b = mid.subtract(BigInteger.ONE);
else a = mid.add(BigInteger.ONE);
}
return a.subtract(BigInteger.ONE);
}
To know more about zeisel numbers
A Zeisel number is a square-free integer k with at least three prime factors which fall into the pattern
p[x] = a*p[x-1] + b
where a and b are some integer constants and x is the index number of each prime factor in the factorization, sorted from lowest to highest. For the purpose of determining Zeisel numbers, p[0] = 1.
I have written this code below in java. This function does test for positive b but not for negative b. How can I do that?
// function to caluculate zeisel number
public static boolean zeisel(int num) {
// returning false if not squarefree
if (Math.sqrt(num) == (int) Math.sqrt(num))
return false;
int fac = 2, count = 0, str = num;
// arrray to store prime factors
int[] fact;
int a = 1, b = 0, i = 0;
// counting number of factors
while (num != 1) {
if(num % fac == 0) {
count++;
num /= fac;
}
else
fac++;
}
num = str;
fac = 2;
// storing factors in array
fact = new int[count];
while (num != 1) {
if(num % fac == 0) {
fact[i] = fac;
i++;
num /= fac;
} else
fac++;
}
if(i < 3)
return false;
// checking for zeisel equation
while(a < fact[0]) {
b = fact[0] - a;
for(i = 1; i < count; i++) {
if(fact[i] != a*fact[i -1] + b) {
break;
}
}
if(i == count) {
return true;
}
a++;
}
return false;
}
There is no need for any looping to determine the a and b factors. You have two equations in two unknowns:
p1 = a * (1) + b
p2 = a * p1 + b
Subtracting the first from the second gives:
p2 - p1 = a * (p1 - 1)
Which you can use to directly solve for a = (p2 - p1) / (p1 - 1), and assuming it is an integer, then solve for b = p1 - a.
So, after you've generated your factors in fact[] (with the corrected square-free condition), your test could be something like:
if ((fact[1] - fact[0]) % (fact[0] - 1) != 0)
return false;
int a = (fact[1] - fact[0]) / (fact[0] - 1);
int b = fact[0] - a;
for(int i=2; i<count; i++) {
if (fact[i] != a*fact[i-1] + b) {
return false;
}
}
return true;
I currently have a program to find the prime factorisation of a given number; works fine with smaller numbers, but it takes ages for anything over a million. My code is extremely inefficient, finding all prime numbers below the input and checking which ones divide without a remainder. I don't know how to make it less inefficient, any help?
static ArrayList<Integer> primeNumbersBelow(long n) {
ArrayList<Integer> ay = new ArrayList<Integer>();
ay.add(2);
for(int i = 3; i < ((n % 2 != 0) ? (n + 1) / 2 : n / 2); i++) {
boolean divides = false;
for(int j = 2; j < i; j++) {
if(i % j == 0) {
divides = true;
}
}
if(!divides) {
ay.add(i);
System.out.println(i);
}
}
return ay;
}
static ArrayList<Integer> primeFactorisationOf() {
ArrayList<Integer> ay = new ArrayList<Integer>();
ArrayList<Integer> aay = primeNumbersBelow(input);
long n = input;
for(int i = 0, len = aay.size(); i < len; i++) {
int f = aay.get(i);
boolean run = true;
while(run) {
if(n % f == 0) {
ay.add(f);
n /= f;
} else {
run = false;
}
}
}
return ay;
}
From Mr Lars Vogel # vogella...
public static List<Integer> primeFactors(int number) {
int n = number;
List<Integer> factors = new ArrayList<Integer>();
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
return factors;
}
Sticking to your general algorithm and not re-writing your primesBelow(..) method: I would say:
Once divides = true, you can break out of the for-loop
The complex for loop termination condition for primality check can be reduced to the Math.sqrt(n) - I won't go through the math, but you can look that up yourself.
One way to improve the code is to remove the IO inside your loop structure.
That is,
static ArrayList<Integer> primeNumbersBelow(long n) {
ArrayList<Integer> ay = new ArrayList<Integer>();
ay.add(2);
for(int i = 3; i < ((n % 2 != 0) ? (n + 1) / 2 : n / 2); i++) {
boolean divides = false;
for(int j = 2; j < i; j++) {
if(i % j == 0) {
divides = true;
}
}
if(!divides) {
ay.add(i);
//REMOVE THE FOLLOWING LINE
System.out.println(i);
}
}
return ay;
}
I'm sure you'll see a huge performance boost just from that alone.