Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I wanna write a recursive method that follows this logic:
suppose if the array is [3, 3, 3, 3] it will return a value of 30 because the consecutive number for trail[i] are equal to each other. So what happens here is 3 + (3 * 2) + (3 * 3) + (3 * 4) = 30
Another example is [2, 4, 3] it will return a value of 9
I hope this makes sense
Can anyone help?
Why do you need recursion for this?
Simple loop should do the job:
public int sum(int[] arr) {
int sum = 0;
for (int i = 0, p = 0; i < arr.length; i++) {
if (i == 0 || arr[i] == arr[i - 1]) {
p++;
} else {
p = 1;
}
sum += arr[i] * p;
}
return sum;
}
update
Java 8 Stream API may be used to produce the same result:
public int sumStream(int[] arr) {
int[] pp = {0};
return IntStream.range(0, arr.length)
// update the quotient for the i-th element
.peek(i -> {
pp[0] = i == 0 || arr[i] == arr[i - 1] ? pp[0] + 1 : 1;
})
.map(i -> pp[0] * arr[i])
.sum();
}
You can try this way
int sum(int pos, int[] trail, int cnt) {
if (pos >= trail.length) { // when full array traversed
return 0;
}
if (pos != 0 && trail[pos - 1] == trail[pos]) { // if previous element is same
return (cnt + 1) * trail[pos] + sum(pos + 1, trail, cnt + 1);
} else { // first element or prev not same
return trail[pos] + sum(pos + 1, trail, 1);
}
}
And call this way sum(0, trail, 0)
As others already mentioned that this could be easily written as an interative function without using recursion but if for some reason you still want a recursive function then it will be something like below:
int recursiveHelper(int[] nums, int index, int pow){
if(index >= nums.length) return 0;
if(index == 0)
return nums[0] + recursiveHelper(nums, index+1,0);
else{
if(nums[index] == nums[index-1])
return nums[index] * pow + recursiveHelper(nums, index, pow+1);
else
return nums[index] + recursiveHelper(nums, index+1,0);
}
}
Notice how we pass the pow variable to track the repetition of integers. If a number is not equal to its previous number, we ignore pow and set it 0. If it is equal to previous number, we increment pow and call the recursive function.
Note : I didn't execute this, there may be some typos and errors here but this should give you an idea on how to start.
int[] values = new int[]{3,3,3,3};
int currentNumber=0,previousNumber=-1,count=1,sum=0;
for(int i = 0; i<values.length;i++,previousNumber = currentNumber){
currentNumber = values[i];
if(currentNumber == previousNumber){
count++;
}else{
count=1;
}
sum += currentNumber*count;
}
System.out.println("Sum : " + sum);
Related
I have an assignment to submit and I need help I will appreciate it a lot!!
I need to write a method that gets an integer matrix grid with numbers from 0 and above. 1 value in the matrix is different and contains -1. the function also gets the starting x and y in the matrix.
I need to write a recursive function that finds the shortest path from the starting x, y to the -1 value.
you can "jump" to the left' right' up and down. the condition to "jump" from one index to another is if the absolute value between the subtraction of the the 2 pairing is either 0, 1 or 2
The shortest path is 4
I cannot use while and for loops, and global variables
The function signature should be: public static int shortestPath(int[][] drm, int i, int j)
Thanks a lot!
Here is my try:
package assignment1;
import java.util.*;
public class run {
static Scanner reader = new Scanner(System.in);
public static int shortestPath(int[][] drm, int i, int j) {
if (drm.length == 0 || i >= drm.length || j >= drm.length || i < 0 || j < 0)
return 0;
if (i > 0 && j > 0 && i < drm.length - 1 && j < drm[i].length - 1) {
if (drm[i][j - 1] == -1) {
System.out.print("Got it! the target is on the left");
return 2;
}
if (drm[i][j + 1] == -1) {
System.out.print("Got it! the target is on the right");
return 2;
}
if (drm[i - 1][j] == -1) {
System.out.print("Got it! the target is up");
return 2;
}
if (drm[i + 1][j] == -1) {
System.out.print("Got it! the target is down");
return 2;
}
}
int temp = drm[i][j];
int left = Integer.MAX_VALUE, right = Integer.MAX_VALUE, up = Integer.MAX_VALUE, down = Integer.MAX_VALUE;
if (isValidJump(drm, i, j, i + 1, j)) {
System.out.print("down ");
drm[i][j] = Integer.MIN_VALUE;
down = shortestPath(drm, i + 1, j) + 1;
}
if (isValidJump(drm, i, j, i, j + 1)) {
System.out.print("right ");
drm[i][j] = Integer.MIN_VALUE;
right = shortestPath(drm, i, j + 1) + 1;
}
if (isValidJump(drm, i, j, i, j - 1)) {
System.out.print("left ");
drm[i][j] = Integer.MIN_VALUE;
left = shortestPath(drm, i, j - 1) + 1;
}
if (isValidJump(drm, i, j, i - 1, j)) {
System.out.print("up ");
drm[i][j] = Integer.MIN_VALUE;
up = shortestPath(drm, i - 1, j) + 1;
}
drm[i][j] = temp;
return Math.min(Math.min(Math.min(up, down), left), right);
}
public static boolean isValidJump(int[][] drm, int i, int j, int m, int n) {
if (m < drm.length && m >= 0 && n < drm.length && n >= 0 && drm[m][n] != Integer.MIN_VALUE) {
int jump = drm[m][n] - drm[i][j];
if (jump == 0 || jump == 1 || jump == -1 || jump == -2) {
return true;
}
}
return false;
}
public static void main(String[] args) {
int[][] drm = { { 2, 0, 1, 2, 3 }, { 2, 3, 5, 5, 4 }, { 8, -1, 6, 8, 7 }, { 3, 4, 7, 2, 4 },
{ 2, 4, 3, 1, 2 } };
System.out.println(shortestPath(drm, 0, 0));
}
}
It supposed to return 4 (shortest path)
Given this is for a class I advise you to notify your professor that you received assistance from this post on stack overflow. Neglecting to do this would be considered academic dishonestly at most universities.
Second thing is as David suggested this is a good opportunity for you to learn how to use a debugger. This is a skill that will be incredibly valuable in your academic career and in a engineering role.
Your Code
Now looking at your code it does give the solution "4" for the case you presented which is correct. Problem is if you change the inputs the output may not give the correct answer.
This is because your code as written gives the FIRST path it finds and not the SHORTEST path.
Your logic as far as the recursion is sound and based on this code it looks like you understand the basics of recursion. Your problem is a minor logical flaw with how your are masking your data when you call your function recursively.
You should have everything you need to solve this. If you are still having problems please try to use a debugger and examine the area where you make your recursive calls.
Solution
I advise you to try to figure this out yourself before looking at the spoilers below.
In the code where you make your recursive calls you mask by setting drm[i][j] = Integer.MIN_VALUE. The problem is after each of your recursive calls return you do not set it back to the previous value with drm[i][j] = temp before doing the tests for your next recursive call.
What is happening is when you next call isValidJump() it will always return false because drm[i][j] will always be Integer.MIN_VALUE after your have made your first recursive call on this iteration.
How to fix:
Put drm[i][j] = temp immediately after each recursive call to shortestPath().
i want to transform this function to recursive form could anyone help me thx
that function is to solve this stuff
X=1+(1+2)*2+(1+2+3)*2^2+(1+2+3+4)*2^3+ . . . +(1+2+3+4+. . . +n)*2^(n-1)
public static int calcX(int n) {
int x=1;
int tmp;
for(int i = 1 ; i <= n-1;i++) {
tmp=0;
for(int j = 1 ; j <= i + 1;j++) {
tmp+=j;
}
x+=tmp*Math.pow(2, i);
}
return x;
}
my attempt im new to recursive stuff
public static int calcXrecu(int n,int tmp,int i,int j) {
int x=1;
if(i <= n-1) {
if(j <= i) {
calcXrecu(n,tmp+j,i,j+1);
}
else {
x = (int) (tmp*Math.pow(2, i));
}
}
else {
x=1;
}
return x;
}
You have a sequence of sums which themselves are sums.
The nth term can be derived from the (n-1)th term like this:
a(n) = a(n-1) + (1+2+3+....+n) * 2^(n-1) [1]
and this is the recursive formula because it produces each term via the previous term.
Now you need another formula (high school math) for the sum of 1+2+3+....+n:
1+2+3+....+n = n * (n + 1) / 2 [2]
Now use [2] in [1]:
a(n) = a(n-1) + n * (n + 1) * 2^(n-2) [3]
so you have a formula with which you can derive each term from the previous term and this is all you need for your recursive method:
public static int calcXrecu(int n) {
if (n == 1) return 1;
return calcXrecu(n - 1) + n * (n + 1) * (int) Math.pow(2, n - 2);
}
This line:
if (n == 1) return 1;
is the exit point of the recursion.
Note that Math.pow(2, n - 2) needs to be converted to int because it returns Double.
In addition to #forpas answer, I also want to provide a solution using corecursion by utilizing Stream.iterate. This is obviously not a recursive solution, but I think it is good to know alternatives as well. Note that I use a Pair to represent the tuple of (index, value).
public static int calcXcorecu(final int n) {
return Stream.iterate(
Pair.of(1, 1), p -> {
final int index = p.getLeft();
final int prev = p.getRight();
final int next = prev + index * (index + 1) * (int) Math.pow(2, index - 2);
return Pair.of(index + 1, next);
})
// only need the n-th element
.skip(n)
.limit(1)
.map(Pair::getRight)
.findFirst()
.get();
}
I am trying to write the code for recursive function which prints every power of 2 from 1 to N, N is the argument of power function.
Function : int powers(n)
Currently I wrote this code:
int powers(int n) //here n=128
{
if(n==2)
{
System.out.print(n);
}
else if (n>2)
{
System.out.print(n +", ");
return powers(n/2);
}
System.out.println("");
return 0;
}
Output : 128, 64, 32, 16, 8, 4, 2
Expected : 2, 4, 8, 16, 32, 64, 128
As the purpose of your function is printing the powers of 2, you do not need to return the value. Hence, you can rewrite your function as the following:
int powers(int N) //here N=128
{
if(N==2){
System.out.print(N + ", ");
}
else if (N >2)
{
powers(N/2);
System.out.print(N + ", ");
}
System.out.println("");
return 0;
}
Also to handle the last extra comma you can return the previous step string and print outside the function.
String powers(int N) //here N=128
{
if(N==2){
return (N + "");
}
String prev = powers(N/2);
return (prev + ", " + N);
}
I think this would be a more elegant way to achieve this. Improvements are supposed to be:
Use bit shifting when possible to gain some
performance.
Fix comma placement for all cases of input N
More elegant looking code
int powers(int N) //here N=128
{
if (N < 2) return 0;
powers(N >> 1); // Right shifting achieves division by 2 but a lot faster.
if (N > 3) System.out.print(", "); // Fixing comma placement for all cases of N.
System.out.print(N);
return 0;
}
Why are we making the assumption that the input N is already a power of 2? Besides, 2 ^ 0 = 1, should that be in the result as well?
public int power(int num) {
if (num <= 0)
return -1;
else if (num <= 1) {
System.out.print(1);
return 1;
} else if (num <= 2) {
System.out.print(1 + ", " + 2);
return 2;
} else {
int result = 2 * power(num / 2);
System.out.print(", " + result);
return result;
}
}
This works even if you give 131 as the input.
I am trying to find if there exist a subset that its sum equals the goal then prints it. I am new in java and recursion is a bit confusing sometimes
void sumOfSubsets(int n, int[] w, int W) {
if (W == 0)
return;
if ((W < 0) || (n < 0))
return;
if (W == 0) {
System.out.print(w[n] + " ");
return;
}
sumOfSubsets(n - 1, w, W);
}
In general recursion becomes less confusing if you ask yourself:
What's a very simple situation that has an obvious answer; and
How can I make a non-simple situation into a simple one
In your case the answer are:
if the subset is empty, then only a target sum of 0 satisfies the condition
if the subset isn't empty, check if the set without the first item has a subset that equals the sum, or the sum minus the first item
Translating those answers to code:
boolean hasSumEqualTo(List<Integer> list, int sum) {
if (list.isEmpty())
return sum == 0;
int first = list.remove(0);
return hasSumEqualTo(list, sum) || hasSumEqualTo(list, sum - first);
}
Or, using arrays:
boolean hasSumEqualTo(int i, int[] list, int sum) {
if (i == list.length)
return sum == 0;
return hasSumEqualTo(i + 1, list, sum) || hasSumEqualTo(i + 1, list, sum - list[i]);
}
If you just want to print all subsets:
void printSubsetsThatSumTo(String current, List<Integer> list, int sum) {
if (list.isEmpty()) {
if (sum == 0)
System.out.println(current);
} else {
int first = list.remove(0);
printSubsetsThatSumTo(current, list, sum);
printSubsetsThatSumTo(current + " " + first, list, sum - first);
}
}
In all cases the pattern is exactly the same.
I am keen to find out the following:
Given a set with N elements, my friend and I are playing a game.I always make the first move.
We can only remove either the first or the last element with 50% chance each.We take alternate turns in the game.If only one element remains,we can remove it for sure.What is the expected sum that I can collect?
For example:N=2 {10,20} Possible sets that I can collect are {10},{20}.
So expected sum is 0.5*10+0.5*20=15.
My approach:
Since probability of getting a possible sum is equal in all cases,we only need to compute the sum of all possible sums and then multiply it by (0.5)^N/2.
I tried to use recursion to compute the required sum:
f(i,j)-computes the sum between i and j recursively
f(i,j)=2*a[i]+func(i,j-2)+func(i+1,j-1)+func(i+1,j-1)+func(i+2,j)+2*a[j]);
Initial call f(1,N)
But the approach doesn't seem to work. What should I do?
Complete function is below:
class CandidateCode {
static long v[][] = new long[1003][1003];
public static long func(int a[], int i, int j) {
if (i == j)
return v[i][j] = a[i];
if (v[i][j] != 0)
return v[i][j];
else {
if (i > j - 2 && i + 1 > j - 1 && i + 2 > j)
return (v[i][j] += 2 * a[i] + 2 * a[j]);
else
return (v[i][j] += 2 * a[i] + func(a, i, j - 2) + func(a, i + 1, j - 1) + func(a, i + 1, j - 1)
+ func(a, i + 2, j) + 2 * a[j]);
}
}
public static void main(String args[]) {
int n;
int a[] = { 0, 6, 4, 2, 8 };
n = a.length - 1;
System.out.println(func(a, 1, 4) / Math.pow(2, n / 2));
}
}
This problem can be solved by applying dynamic programming.
First, we have the state of the game is (player ,start, end) ,which indicates the current player, and the range of values that's available in the original set. At the beginning, we start at player 0 and start is 0, end is N - 1.
Denote that the first player is 0 and the second player is 1, we have the expected value of player 0:
if(player == 0){
double result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
}else{
double result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
}
So for each state, we can store all calculated state in a dp[player][start][end] table, which reduce the time complexity to O(2*N*N) with N is number of value in set.
Pseudo code:
double expectedValue(int player, int start, int end, int[]set){
if(start == end)
if(player == 0)
return set[start];
return 0;
if(already calculated this state)
return dp[player][start][end];
double result= 0;
if(player == 0){
result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
}else{
result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
}
return dp[player][start][end] = result;
}