I have to calculate a sum of two integers by using a recursive algorithm, but sincerely i have no idea how to do so. Here are the conditions:
sum(x,y) = ?
if x = 0 then sum (x,y) = y otherwise sum(x,y) = sum(predecessor(x),successor(y)).
Does someone have an idea how i could write this in an algorithm? I would be glad about any advice.
I won't give you the code since this seems to be a homework but here is the rough algorithm:
predecessor(x) = x - 1
successor(x) = x + 1
sum(x, y) =
if x = 0
then y
otherwise sum(predecessor(x), successor(y))
That's the simplest I could immagine
public static void main(String[] args) {
System.out.println("4+5 = " + sum(4, 5));
System.out.println("4+(-5) = " + sum(4, -5));
System.out.println("-4+5 = " + sum(-4, 5));
System.out.println("-4+5 = " + sum(-4, -5));
}
public static int sum(int x, int y) {
if (x < 0) {
x *= -1;
y *= -1;
}
return (x == 0 ? y : sum(--x, ++y));
}
Here is my solution for i&j both >= 0. set sum = 0; and subtract 1 until it is <= 0
public static int sum(int i, int j){
return sum(i,j,0);
}
private static int sum(int i, int j, int sum) {
if (i <= 0 && j <= 0) {
return sum;
} else if (i <= 0) {
return sum(0, j - 1, sum + 1);
} else if (j <= 0) {
return sum(i - 1, 0, sum + 1);
} else {
return sum(i - 1, j - 1, sum + 2);
}
}
public static void main(String[] args) {
System.out.println(sum(60, 7));
}
To handle negative numbers based on #aioobe's answer.
sum(x, y): return x == 0 ? y : x < 0 ? ~sum(~x, -y) : sum(x-1, y+1)
Note: the rather optimisic use of ~ to avoid blowing up on x=MIN_VALUE. ;)
Javaish pseudo code corresponding to your code in your question
sum(x, y): return x == 0 ? y : sum(x-1, y+1)
Works for any pair of numbers where x is a non-negative integer.
Related
Below is the code of recursive Fibonacci, and it causes a stackoverflowerror. Why does just changing the condition from n==1 to n<2 make it work?
Consider the normal Fibonacci function: F(n) = F(n - 1) + F(n - 2). That function can be represented here as F(n) = calculate(n, 2).
The concept here is that calculate(n, x) = calculate(n - 1, x) + calculate(n - 2, x) + calculate(n - 3, x) + ...+ calculate(n - x, x);
public static int calculate(int n, int x) {
if (n == 1) {
return n;
}
else {
int output = 0;
for (int i = 1; i <= x; i++) {
output += calculate(n - i, x);
}
return output;
}
}
}
When your stopping condition is just n == 1, calculate won't stop if you pass to it 0 or negative values, which is what you are doing in your loop.
For example, if n == 2 and x == 2, calculate(n - i, x) becomes calculate(0,2) when i == x.
Therefore, if (n <= 1) or if (n < 2) is the correct stopping condition.
I'm just starting java, and have written a simple program for returning factors of input numbers. There are two classes, a tester and a the one you see below.
Unfortunately, my output, say if I input 150, is 2, 3, 0, 5, 5.
I know why this is happening; when the local variable q = i, we obviously get 2, 3, 5, 5, but when the conditional in the first if statement is not met, q is read as 0.
Is there a way to exclude a specific integer, in this case 0, from the output? I've struggled with what should be an easy problem for hours, so obviously I'm not seeing something.
I realize there are easier ways to write this program, but all methods must remain as is...
public class FactorGenerator {
private int y;
private int i;
public FactorGenerator(int numberToFactor)
{
y = numberToFactor;
i = 2;
}
public boolean hasMoreFactors()
{
if (i <= y)
{
return true;
}
else
{
return false;
}
}
public int nextFactor()
{
int q=0;
if( y % i != 0)
i++;
if( y % i == 0)
{
y = y / i;
q = i;
}
return q;
}
}
Quick fix. You need a while loop (to skip all factors that does not clearly divide your y) in here:
if( y % i != 0)
i++;
Like this:
while( y % i != 0){
i++;
}
#MicD has suggested correct answer
Another way:
As you have problem with zero, so just check q is not equal to zero
int nextFactor()
{
int q=0;
if( y % i != 0)
i++;
if( y % i == 0)
{
y = y / i;
q = i;
}
if(q!=0)
return q;
else
nextFactor();
}
I am trying to create a recursion function that allows me to "simulate" a double for loop. Something similar to
Iterative:
for(int i = 0; i < list.length; i++) {
for(int x = i; x < list.length; x++) {
//handle logic here
}
}
Recursive:
public int solve(int start_index, int end_index) {
if(start_index >= array.length) { return 0; }
if(end_index >= array.length - 1) { solve(start_index + 1, 0); return 0; }
return solve(start_index, end_index + 1);
}
But it doesn't seem to return results similar to I think it should. Can any one help me out? Appreciate it!
Lets say your operation is a sum of an integer array. That's the iterative version:
for (int i = 0; i < array.length; i++)
for (int x = i; x < array.length; x++)
sum1 += array[x];
The recursive version will be something like:
public int solve(int x, int i, int end)
{
if(i == end)
return array[x];
else if(x == end)
return array[x] + solve(i + 1, i + 1, end);
else
return array[x] + solve(x + 1, i, end);
}
We would call it with sum2 = solve(0, 0, array.length-1);
The semantics of the variables i and x is the same on both the versions for better understanding.
In the end sum1 will be the same as sum2.
This should work (Note I am simulating similar behavior):
public class temp {
// This will be the method to simulate the double for loop you had
// listed in your question.
static void iterate(int index, int sub_index, int end_index) {
if (index < end_index){
if (sub_index < end_index ){
System.out.println(index + " " + sub_index );
iterate(index, sub_index + 1 , end_index);
}else {
iterate(index + 1, index+1 , end_index) ;
}
}
}
public static void main(String[] args){
// Simulate the usual double for loop
System.out.println("Double for loop");
for (int i = 0 ; i < 3 ; i++){
for (int j = i ; j < 3 ; j++){
System.out.println(i + " " + j);
}
}
// Simulate the double for loop through recursion
System.out.println("Double for loop through recursion");
iterate(0,0,3);
}
}
and the output will be:
Double for loop
0 0
0 1
0 2
1 1
1 2
2 2
Double for loop through recursion
0 0
0 1
0 2
1 1
1 2
2 2
I want to find the sum of numbers that is divisible by x using recursive method
Ex if n= 10, x=3, the code should return sum of 3+6+9
Write a recursive method sumDivByX(n, x), which finds the sum of all
numbers from 0 to n that are divisible by x.
I asked my teacher about it and he told me "Firstly, total should be global. You should return 0 if n or x == 0. I only care if n is divisible by x. So I only add n to total (total+=n) if (n%x==0) otherwise do nothing. And do recursion sumDivByX(n-1,x) and return total as usual." I tried to correct it.
public static int sumDivByX(int n, int x) {
int total = 0;
if (n == 0 || x == 0) {
return -1;
}
if (n % x >= 1) {
return total = 0;
} else if (n % x == 0) {
return total += n;
}
return total + sumDivByX(n - 1, x);
}
When I run the program I get 0.
Eliminate the returns inside your second and third if statements
public static int sumDivByX(int n, int x) {
int total = 0;
if (n == 0 || x == 0) {
return 0;
}
if (n % x >= 1) {
total = 0;
} else if (n % x == 0) {
total += n;
}
return total + sumDivByX(n - 1, x);
}
For a cuter, more compact version
public static int sumDivByX(int n, int x) {
if (n == 0 || x == 0) {
return 0;
}
return (n % x == 0 ? n : 0) + sumDivByX(n - 1, x);
}
Note - depending on the semantics you intend, you might want to have separate checks for x<=0 (possibly and error?) and n==0 (base case).
Step through your code and you'll see that it never recurses when n ==10 and x==3, since (10 % 3 == 1)
When a method gets to a "return" statement it ends, in your case at the second if.
Your total is initialized by 0 everytime the method runs, so you should consider making it global.
Your method generates an exception if you try to use negative numbers as paramethers
Try this:
int total=0;
public static int subDivByX(int n, int X) {
if (n>0 && x>0) {
if (n%x==0){
total += n;
}
return sumDivByX(n-1,x);
}
else return -1;
}
This seems to work
private static int sumDivByX(int n,int x) {
if (n < x || x < 1 ) {
return 0;
}
int d = n/x;
return (x * d) + sumDivByX(n - x , x);
}
Recursion could cause a stackoverflow.
I'm trying to solve this problem on topcoder as a practice , I tried implementing DFS solution for it , it works well except for a bug : it keeps traversing every unvisited cell even if it reached a dead end , the initial code was :
public void func(int[][] x, StringBuilder s, int i, int j, int n) {
if (i < 0 || j < 0 || i > n || j > n || x[i][j] == 1) {
return;
}
s.append((char) (97 + j));
s.append(n - i + 1 + "-");
x[i][j] = 1;
func(x, s, i, j + 1, n);
func(x, s, i - 1, j, n);
func(x, s, i + 1, j, n);
func(x, s, i, j - 1, n);
return;
}
public String dukePath(int n, String initPosition) {
String p = initPosition;
int x[][] = new int[n][n];
StringBuilder s = new StringBuilder("");
func(x, s, n - Integer.parseInt(p.charAt(1) + ""), (int) p.charAt(0) - 97, n - 1);
s.replace(s.length() - 1, s.length(), "");
if (s.length() > 40) {
s.replace(20, s.length() - 20, "...");
}
return s.toString();
}
so I tried to modify the signature of the function "func()" by adding a boolean flag , and initial position (z,y) to compare the current cell with ; if the code tries to revisit the initial position then it should return , but it also didn't work..
How could I stop traversing when reaching a dead-end or the initial position again ?
You are approaching this problem incorrectly, all you need to do is to move to the lexicographically greatest neighbour at every step until you reach a point where you have visited all neighbouring cells. This is simple iteration and doesn't require DFS:
public static String dukePath(int n, String initPosition) {
int x = initPosition.charAt(0) - 'a';
int y = n - (initPosition.charAt(1) - '0');
boolean grid[][] = new boolean[n][n];
StringBuilder s = new StringBuilder(initPosition);
while (true) {
grid[x][y] = true;
if (x < (n - 1) && !grid[x + 1][y])
x++; // Right
else if (y > 0 && !grid[x][y - 1])
y--; // Up
else if (y < (n - 1) && !grid[x][y + 1])
y++; // Down
else if (x > 0 && !grid[x - 1][y])
x--; // Left
else
break; // Nowhere left to go!
s.append("-" + (char)('a' + x) + (char)('0' + n - y));
}
if (s.length() > 40) {
s.replace(20, s.length() - 20, "...");
}
return s.toString();
}
public static void main(String args[])
{
System.out.println(dukePath(3, "b2"));
System.out.println(dukePath(4, "d4"));
System.out.println(dukePath(3, "a2"));
System.out.println(dukePath(4, "d3"));
System.out.println(dukePath(8, "a8"));
}
Gives the expected results:
b2-c2-c3-b3-a3-a2-a1-b1-c1
d4-d3-d2-d1-c1-c2-c3...b3-b2-b1-a1-a2-a3-a4
a2-b2-c2-c3-b3-a3
d3-d4-c4-c3-c2-d2-d1...b2-b3-b4-a4-a3-a2-a1
a8-b8-c8-d8-e8-f8-g8...a1-a2-a3-a4-a5-a6-a7
I think the simplest solution is to create a set of objects containing i and j. In every call of func if this set contains the target object with i and j, it should not call the func function. This method both covers step backs and loops.