I can't seem to figure this one out. I need to count how many numbers below a given number in which it is divisible.
Here is what I've tried:
public int testing(int x) {
if (x == 0) {
System.out.println("zero");
return x;
}
else if ((x % (x-1)) == 0) {
System.out.println("does this work?");
x--;
}
return testing(x-1);
}
That doesn't work and I don't know where to go from here. Anyone know what to do?
This is what is wrong:
public int testing(int x) {
If you want to make it recursive, you need to pass both the number to test and the number that you are currently checking. The first one will not change through the recursion, the second one will decrement. You cannot do what you express with only one parameter (unless you use a global variable).
This is not a task that should be solved with recursion.
If you MUST use recursion, the simplest way to do it is to have a second parameter, which is essentially an "I have checked until this number". Then you can increase/decrease this (depending on if you start at 0 or the initial number) and call the recursive on that.
Thing is, Java isn't a functional language, so doing all this is actually kind of dumb, so whoever gave you this exercise probably needs a bop on the head.
Your problem is that your expression x % (x - 1) is using the "current" value of x, which decrements on every call to the recursive function. Your condition will be false all the way down to 2 % (2 - 1).
Using a for loop is a much better way to handle this task (and look at the Sieve of Eratosthenes), but if you really have to use recursion (for homework), you'll need to pass in the original value being factored as well as the current value being tried.
You have a problem with your algorithm. Notice the recursion only ends when x == 0, meaning that your function will always return 0 (if it returns at all).
In addition, your algorithm doesn't seem to make any sense. You are basically trying to find all factors of a number, but there's only one parameter, x.
Try to make meaningful names for your variables and the logic will be easier to read/follow.
public int countFactors(int number, int factorToTest, int numFactors)
{
if (factorToTest == 0) // now you are done
return numFactors;
else
// check if factorToTest is a factor of number
// adjust the values appropriately and recurse
}
There is no need to use recursion here. Here's a non-recursive solution:
public int testing(int n) {
int count = 0;
for (int i = 1; i < n; i++)
if (n % i == 0)
count++;
return count;
}
BTW, you should probably call this something other than testing.
Using recursion:
private static int getFactorCount(int num) {
return getFactorCount(num, num - 1);
}
private static int getFactorCount(int num, int factor) {
return factor == 0 ? 0 : (num % factor == 0 ? 1 : 0)
+ getFactorCount(num, factor - 1);
}
public static void main(String[] args) {
System.out.println(getFactorCount(20)); // gives 5
System.out.println(getFactorCount(30)); // gives 7
}
Related
I'm learning recursion now, and I thought I quite understood how recursion works, and then I saw this code, and my head is about to explode.
I know this simple recursion works like
public void recursivePrint(int number){
if(number == 0{
return;
}
System.out.println(number + " ");
recursivePrint(number - 1);
}
If the parameter "number"'s value is 2.
public void recursivePrint(2){
if(number == 0{
return;
}
System.out.print(2 + " ");
recursivePrint(2 - 1);
}
public void recursivePrint(1){
if(number == 0{
return;
}
System.out.print(1 + " ");
recursivePrint(1 - 1);
}
and then stops because it meets its base case.
What about this print all permutations of a string function?
private void permute(String str, int l, int r)
{
if (l == r)
System.out.println(str);
else
{
for (int i = l; i <= r; i++)
{
str = swap(str,l,i);
permute(str, l+1, r);
str = swap(str,l,i);
}
}
}
There is a recursive call inside a for loop. If the input value is "ab", how does this recursion function work? Can you explain as I wrote above?
I got this code form geeksforgeeks, and there's a video for this, but I can't understand this since I don't know how loop works in recursion.
Using permute function you are generating strings where lth char is being replaced by one of the char following it. With the for loop inside it, you are touching onto each of those following characters one at a time.
With several call to permute, you are able to advance till the end position of the string, and that end is checked by if (l == r)
Take the case of abc.
abc
/ | \
Level 1 a(bc) b(ac) c(ba) (Here three new call to permute are made out of permute with l=1)
Goes on...
FYI, permutation isn't that simple to understand if you are new to recursion or programming. For easy understanding use pen-paper.
Recursion occurs when a method calls itself. Such a method is called recursive. A recursive method may be more concise than an equivalent non-recursive approach. However, for deep recursion, sometimes an iterative solution can consume less of a thread's finite stack space.
What is recursion:
In general, recursion is when a function invokes itself, either directly or indirectly. For example:
// This method calls itself "infinitely"
public void useless() {
useless(); // method calls itself (directly)
}
Conditions for applying recursion to a problem:
There are two preconditions for using recursive functions to solving a specific problem:
There must be a base condition for the problem, which will be the endpoint for the recursion. When a
recursive function reaches the base condition, it makes no further (deeper) recursive calls.
Each level of recursion should be attempting a smaller problem. The recursive function thus divides the problem into smaller and smaller parts. Assuming that the problem is finite, this will ensure that the recursion terminates.
In Java there is a third precondition: it should not be necessary to recurse too deeply to solve the problem;
The following function calculates factorials using recursion. Notice how the method factorial calls itself within the function. Each time it calls itself, it reduces the parameter n by 1. When n reaches 1 (the base condition) the function will recurse no deeper.
public int factorial(int n) {
if (n <= 1) { // the base condition
return 1;
} else {
return n * factorial(n - 1);
}
}
there are many questions about how to convert recursive to non-recursive, and I also can convert some recursive programs to non-recursive form
note: I use an generalized way (user defined Stack), because I think it is easy to understand, and I use Java, so can not use GOTO keyword.
Things don't always go so well, when I meet the Backtracking, I am stuck. for example, The subset problem. and my code is here: recursive call with loop
when i use user defined Stack to turn it to non-recursive form. I do not know how to deal with the loop (in the loop existing recursive call).
I googled found that there is many methods such as CPS. and I know there is an iterative template of subset problem. but i only want to use user defined Stack to solve.
Can someone provide some clues to turn this kind of recursive(recursive with loop) to non-recursive form(by using user defined Stack, not CPS etc..) ?
here is my code recursive to non-recusive(Inorder-Traversal), because of there is no loop with recursive call, so i can easily do it. also when recursive program with a return value, I can use a reference and pass it to the function as a param. from the code, I use the Stack to simulated the recursive call, and use "state" variable to the next call point(because java does not allow using GOTO).
The following is the information I have collected. It seems that all of them does not satisfy the question I mentioned(some use goto that java not allowed, some is very simple recursive means that no nested recursive call or recursive call with loop ).
1 Old Dominion University
2 codeproject
----------------------------------Split Line--------------------------------------
Thks u all. after when I post the question... It took me all night to figure it out. here is my solution: non-recursive subset problem solution, and the comment of the code is my idea.
To sum up. what i stuck before is how to deal with the foo-loop, actually, we can just simply ignore it. because we are using loop+stack, we can do a simple judgment on whether to meet the conditions.
On your stack, have you thought about pushing i (the iteration variable)?
By doing this, when you pop this value, you know at which iteration of the loop you were before you pushed on the stack and therefore, you can iterate to the next i and continue your algorithm.
Non-negative numbers only for simplicity. (Also no IntFunction.)
The power function, as defined here, is a very simple case.
int power(int x, int exponent) {
if (exponent == 0) {
return 1;
} else if (exponent % 2 == 0) {
int y = power(x, exponent /2);
return y * y;
} else {
return x * power(x, exponent - 1);
}
}
Now the stack is there to do in the reverse order to a partial result, what you did in recursion with the result.
int power(final int x, int exponent) {
Stack<Function<Integer, Integer>> opStack = new Stack<>();
final Function<Integer, Integer> square = n -> n * n;
final Function<Integer, Integer> multiply = n -> x * n;
while (exponent > 0) {
if (exponent % 2 == 0) {
exponent /= 2;
opStack.push(square);
} else {
--exponent;
opStack.push(multiply);
}
}
int result = 1;
while (!opStack.isEmpty()) {
result = opStack.pop().apply(result);
}
return result;
}
An alternative would be to "encode" the two branches of if-else (odd/even exponent) by a boolean:
int power(final int x, int exponent) {
BooleanStack stack = new BooleanStack<>();
while (exponent > 0) {
boolean even = exponent % 2 == 0;
stack.push(even);
if (even) {
exponent /= 2;
} else {
--exponent;
}
}
int result = 1;
while (!stack.isEmpty()) {
result *= stack.pop() ? result : x;
}
return result;
}
So one has to distinghuish:
what one does to prepare the recursive arguments
what one does with the partial results of the recursive calls
how one can merge/handle several recursive calls in the function
exploit nice things, like x being a final constant
Not difficult, puzzling maybe, so have fun.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have two methods, that I believe can be made better way, but can't find this way.
First:
public int calcPow(long num) {
int count = 0;
while(num/2!=0) {
num = num/2;
count++;
}
return count;
}
The second is:
private long findParentNumber(long value) {
for(int bitNum = 0; bitNum < Long.SIZE; bitNum++) {
if((value & (1L << bitNum)) != 0) {
return value ^ (1L << bitNum);
}
}
throw new RuntimeException("No parent number found");
}
I believe, there are ways to do the same without loops. Can you help?
Cheers!
For the second one, you're unsetting the lowest set bit. There's a relatively well known bithack to do that, though only relatively because it seems that bithacks in general are not well known.
Anyway, it's
return x & (x - 1);
The logic here is that in x - 1, there's a borrow running through the lowest zeroes until it hits the lowest 1-bit, which it unsets. The lowest zeroes are left set, they are then removed by ANDing it with the original number.
You can write the first one in terms of numberOfLeadingZeros, which would be more obviously correct than floating point hacks which always make you think about how accurate they might be (and in any case they're slow, you might be better off with the loop).
Edit: for completeness, that would be 63 - numberOfLeadingZeros(x), it differs from your definition at x = 0 but that's a bad input anyway.
Try this for the first one.
public int calcPow(long num) {
if (num == 0) return 0;
if (num < 0) num = -num;
return Long.numberOfTrailingZeros(Long.highestOneBit(num));
}
Or this suggested by harold
public int calcPow(long num) {
return num == 0 ? 0
: 63 - Long.numberOfLeadingZeros(Math.abs(num));
}
For the first one, you can use the Math.log method that already exists:
public static int log2(long number) {
return (int) Math.floor(Math.log(number) / Math.log(2));
}
or this faster function suggested by saka1029:
public static int log2(long number) {
return number == 0? 0: Long.numberOfTrailingZeros(Long.highestOneBit((number < 0)? number * -1: number));
}
As you can see I also changed the method to static, since I see no point in having to use an Object to get a log when no object is involved. And secondly I changed the names into something more fitting.
For the second one you can use the bit-wise check operator &:
public static long removeSmallBit(long value) {
return value & (value - 1);
}
Essentially you are removing the smallest bit from the variable, and return that number after you change that bit to 0. And as you can see again I made the method static and changed the name. 2nd answered inspired by this answer submitted by harold
Preface
By finding some free time in my schedule, I quested myself into improving my recursion skills (unfortunately). As practice, I want to recreate all the operators by using recursion, the first one being addition. Although I'm kind of stuck.
Question
As implied, I want to recreate the addition operator by only using recursion and conditionals. Although I got a good portion of the code done, there is still one problem as I included a single addition operator. Here is the code (which runs fine and adds as intended in all variations of positive, negative, and zero inputs). I also included some mediocre comments as help.
public class Test {
public static void main(String[] args) {
// Numbers to add
int firstNumb = -5, secondNumb = 3;
// Call the add function and save the result
int result = add(firstNumb, secondNumb);
// Print result
System.out.println(result);
}
/*
* Function recursively takes a number from 'giver' one at a time and
* "gives"/"adds" it to 'receiver'. Once nothing more to "give" (second == 0),
* then return the number that received the value, 'receiver'.
*/
public static int add(int receiver, int giver) {
/*
* Base Case since nothing more to add on. != to handle signed numbers
* instead of using > or <
*/
if (giver != 0) {
/*
* Recursive Call.
*
* The new 'giver' param is the incremental value of the number
* towards 0. Ex: -5 -> -4 , 5 -> 4 (so I guess it may decrement).
*
* The new 'receiver' param is the incremental value based on the
* opposite direction the 'giver' incremented (as to why the
* directionalIncrement() function needs both values to determine
* direction.
*/
return add(directionalIncrement(receiver, giver),
directionalIncrement(giver, -giver));
} else {
// Return 'receiver' which now contains all values from 'giver'
return receiver;
}
}
// Increments (or decrements) the 'number' based on the sign of the 'direction'
public static int directionalIncrement(int number, int direction) {
// Get incremental value (1 or -1) by dividing 'direction' by absolute
// value of 'direction'
int incrementalValue = direction / abs(direction);
// Increment (or decrement I guess)
return number + incrementalValue;
}
// Calculates absolute value of a number
public static int abs(int number) {
// If number is positive, return number, else make it positive by multiplying by -1 then return
number = (number > 0.0F) ? number : -number;
return number;
}
}
The problem is the line that contains return number + incrementalValue;. As mentioned before, the code works with this although doesn't meet my own specifications of not involving any addition operators.
I changed the line to return add(number, incrementalValue); but seems like it cannot break out of the recursion and indeed throws the title of this website, a StackOverflowException.
All help appreciated. Thanks in advance.
Note
Constraint does not include any implicit increment/decrement (i++/i--) nor does it include bitwise. Try and answer towards the specific problem I am having in my own implementation.
public static int add(int a, int b) {
if(b == 0) return a;
int sum = a ^ b; //SUM of two integer is A XOR B
int carry = (a & b) << 1; //CARRY of two integer is A AND B
return add(sum, carry);
}
Shamefully taken from here. All credit goes to its author.
public static int add (int a, int b) {
if (b == 0) return a;
if (b > a) return add (b, a);
add (++a, --b);
}
Just with ++/--.
I have this odd issue I can't explain to myself, when using short if inside of return. This code (see below) should return the value 55 but instead it just returns the argument 10 which I passed to it by value.
I already debugged the function and the recursion works as intended but it never adds the + 1 to the return value.
public static int add(int i) {
return i == 0 ? 0 : add(i - 1) + 1;
}
public static void main(String[] args) {
System.out.println(add(10)); // returns 10
}
How come this doesn't work?
Your code does what you're telling it to. At each recursion step it reduces one from the counter and adds 1 to the result - since it's counting i times, it'll return i.
What you're trying to do is sum the numbers from 0 to i. In order to do this you need to add i and not 1 to the sum each time.
public static int add(int i) {
return i == 0 ? 0 : add(i - 1) + i; // <- like this
}
Since this is likely an exercise, consider implementing factorial recursively to make sure you understand the concept (that is, a function that takes n and returns n * (n-1) * (n-2) ... and so on.