I am trying to write a simple Java program to compute a hailstone sequence using recursion. A hailstone sequence is basically: take a given integer n - if even, the next integer in the sequence is n/2, if odd, the next integer in sequence is n * 3 + 1. I'm trying to return a string with each number separated by a comma, but my algorithm isn't working. Can someone explain why? Thanks!
public static String recursion (int n) {
String s = "";
if (n != 1) {
if (n % 2 == 0) return s + String.valueOf(recursion(n / 2)) + ", ";
else return s + String.valueOf(recursion((3 * n) + 1)) + ", ";
}
else return s + String.valueOf(1);
}
public static void main(String[] args) {
System.out.println(recursion(435));
}
the problem is, you don't print the actual number n. Change your code to:
public static String recursion (int n) {
//set s to the number n
String s = "" + n;
if (n != 1) {
//change position of the separator
if (n % 2 == 0) return s + ", " + recursion(n / 2);
//change position of the separator
else return s + ", " + recursion((3 * n) + 1);
}
else return s;
}
EDIT:
btw. you don't need String.valueOf(), since the result is already a String
Related
I'm new to recursion and don't understand how it works.
This was a classwork problem that had the answer 18, but I don't understand how. From what I know, this should return 6 + 5 + 4 + 3 (3 + m-1 on the recursive line)?
Are the subtraction signs not indicative of subtraction? (assuming that m = 5)
public int test(int m)
{
int value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
return value;
}
6 + 5 + 4 + 3 (3 + m-1 on the recursive line)? Are the subtraction
signs not indicative of subtraction?
No the +3 will happen for every one of the recursive calls, actually what your function is doing is given the value of (m times 3) + 3.
So for m=5 the recursive calls will be like:
Is m = 0 ? No so let us called recursively:
test(4) + 3
m = 4; then test(3) + 3 + 3
m = 3; then test(2) + 3 + 3 + 3
m = 2; then test(1) + 3 + 3 + 3 + 3
m = 1; then test(0) + 3 + 3 + 3 + 3 + 3
m = 0; then exit with 3 + 3 + 3 + 3 + 3 + 3
Hence, for m=5 you get 18.
A side-note you can use the ternary operator to simplify your method to:
static public int test(int m) {
return (m == 0) ? 3 : test(m - 1) + 3;
}
For visualizing what happens, scatter the code with messages:
public int test(int m)
{
System.out.println("entering test("+m+")");
int value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
System.out.println("returning "+value+" from test("+m+")");
return value;
}
Of course this is just the minimal program, you could also show which branch of the if was taken, m-1, and so on.
JavaScript equivalent, so it can run here in the browser:
function test(m) {
console.log("entering test(" + m + ")");
var value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
console.log("returning " + value + " from test(" + m + ")");
return value;
}
console.log("result: "+test(3));
On the longer run it is a good idea to learn using the debugger of the environment you are using. Among other things, debuggers can step through code line-by-line.
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 need to print the factors of a perfect number. Here's the gist of my main class:
ArrayList<Integer> perfNums = new ArrayList<>();
Scanner in = new Scanner(System.in);
System.out.print("Enter the upperbound: ");
upperbound = in.nextInt();
for (int i = 1; i <= upperbound; i++) {
if (isPerfect(i)) { //boolean to check if number is a perfect number
perfNums.add(i);
}
}
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for (int i = 0; i < perfNums.size(); i++) {
System.out.print(perfNums.get(i) + " = ");
printFactor((int)perfNums.get(i));
System.out.println();
}
Here's the printFactor class.
private static void printFactor(int number){
int factor = 1;
while(factor < number){
if (number%factor == 0) System.out.print(factor+ " + ");
//I don't know how to print the + sign otherwise.
factor++;
}
}
And here's a sample output:
Enter the upperbound: 10000
Perfect numbers between 1 and 10000 are:
6 = 1 + 2 + 3 +
28 = 1 + 2 + 4 + 7 + 14 +
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 +
8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 +
I've got the main gist of it but I've struggled with an output issue. Due to the restrictions of my online submission system, my output needs to fit exact specifications.
My question is how do I go about printing all the factors of my perfect number but removing the + sign at the end? (e.g)6 = 1 + 2 + 3
I'm not too sure of many methods to print from a while loop. Would a for-loop be better for my goals? Or are there alternative methods to print the factors of a number?
The least amount of change to address this might be something like this:
private static void printFactor(int number)
System.out.print(1);
int factor = 2;
while (factor<number) {
if (number%factor == 0) System.out.print(" + " + factor);
factor++;
}
}
1 is always a factor, so you can print that before the loop and then prepend + to every subsequent factor.
You should cache the output you want to print into a StringBuilder. Then you are able to remove the last plus sign before you print the whole String. It also has a better performance.
private static void printFactor(int number)
{
StringBuilder output = new StringBuilder();
int factor = 1;
while (factor < number)
{
if (number % factor == 0)
output.append(factor + " + ");
factor++;
}
// remove last plus sign
output.deleteCharAt(output.length() - 1);
// print the whole string
System.out.print(output.toString());
}
Since factor starts from value 1 and number % 1 == 0 will always be true, you might print 1 first and then flip factor and + in System.out.print. Like this:
private static void printFactor(int number) {
if(number > 0) {
System.out.print(1);
}
int factor = 2;
while (factor<number) {
if (number % factor == 0) {
System.out.print(" + " + factor);
}
factor++;
}
}
Not the best solution, but it will do the job.
Try to create a variable String numb and use substring method like this:
String numb ="";
while(factor<number){
if(number%factor == 0)
numb= numb + factor+ " + ";
factor++;
}
System.out.print(numb.substring(0, numb.trim().length()-1));
Just for the sake of using Java 8 :)
private static void printFactor(int number){
System.out.println(IntStream.range(1, number)
.filter(p -> number % p == 0)
.mapToObj(i -> String.valueOf(i))
.collect(Collectors.joining(" + ")));
}
Thanks everyone for the quick response. You all have been a lifesaver, and I managed to pick up some new things to consider when I code in the future.
Anyway, while waiting for a reply I was fiddling with the code and came up with a rather inelegant solution, if anybody's interested. Here's the changes to the main class:
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for(int i=0; i<perfNums.size(); i++){
System.out.print(perfNums.get(i) + " = ");
outputString = printFactor2(perfNums.get(i));
if(outStr.endsWith(" + ")) outStr = outStr.substring(0, outStr.length()-3);
//because the submission system would cry foul with even a single extra space
System.out.println(outStr);
}
And here's the changes to the printFactor class:
private static String printFactor2(int number){
String out = "";
int factor = 1;
while(factor<number){
if(number%factor == 0) out += factor + " + ";
factor++;
}
return out;
}
Basically, what I did was append the factors to a string, then removing the trailing + sign using the substring method. On hindsight, I probably should've called the substring method inside the printFactor class instead. Something like return out.substring(0, out.length()-3); perhaps?
Nevertheless, thanks everyone!
Example:
numbers are [1, 2, 3] and u have +, *
max value is 1+2*3
example [1, 1, 1] , ans is 1+1+1
I can think of a simple recursive algorithm:
private static double helper(double[] arr, int s, int e) {
System.out.println("s= " + s + " e= " + e);
//base case: if single elem, return that eleme
if (e==s) {
return arr[s];
} if (s+1==e) {
return Math.max(arr[s]+arr[e], arr[s]*arr[e]);
} else if (s>e) {
//this should never happen
throw new UnsupportedOperationException("invalid operation");
}
//int mid = s+ ((e-s)/2);
int mid=s;
double fMax = Double.MIN_VALUE;
for (mid=s;mid<e;mid++) {
//divide and conqr route
double lres = helperDQ(arr,s, mid);
double rres = helperDQ(arr,mid+1, e );
System.out.println("s= " + s + " e = " + e + " m = " + mid + " lres= " + lres + " rres= " + rres);
fMax = Math.max(fMax, Math.max(lres*rres, lres+rres));
}
return fMax;
}
private static double findMax(double[] arr) {
return helper(arr, 0, arr.length-1);
}
Is there a better way to do instead of this recursive way? We can prune the recursion by checking for s, e so we dont end up recursing same thing multiple times.
Can't think of an easy dynamic programming approach way.
Any suggestions?
This can actually be solved a lot easier, using some simple math. For any two numbers a and b, the following applies: unless either a = 1 or b = 1 is given, a * b >= a + b is given (assuming a >= 1 and b >= 1). This applies recursively to any set of numbers. Thus the maximum will always be achieved by
int maxNum(int[] nums){
int x = 0;
for(int n : nums)
if(n == 1)
x += n;
else
if(x == 0)
x = n;
else
x *= n;
return x;
}
If the set of numbers is order.
I am working on a program where I have to use recursion to calculate the sum of 1/3 + 2/5 + 3/7 + 4/9 + ... + i / (2i + 1). However, I am not sure how to make my program show the term that must be added in order to reach the number enter by the user. For example. If I enter 12, I want to know how many terms of the series [1/3 + 2/5 + 3/7 + 4/9 + ... + i / (2i + 1)] were added to get approximately to the number 12.
What I don't want to get is the sum of inputting 12 which in this case is 5.034490247342584 rather I want to get the term that if I were to sum all numbers up to that term I would get something close to 12.
Any help will be greatly appreciated!
This is my code
import java.util.Scanner;
public class Recursion {
public static void main(String[] args) {
double number;
Scanner input = new Scanner(System.in);
System.out.println("Enter a value= ");
number = input.nextInt();
System.out.println(sum(number) + " is the term that should be added in order to reach " + number);
}
public static double sum(double k) {
if (k == 1)
return 1/3;
else
return ((k/(2*k+1))+ sum(k-1));
}
}
You have this question kind of inside out. If you want to know how many terms you need to add to get to 12, you'll have to reverse your algorithm. Keep adding successive k / (2k + 1) for larger and larger k until you hit your desired target. With your current sum method, you would have to start guessing at starting values of k and perform a sort of "binary search" for an acceptably close solution.
I don't think that this problem should be solved using recursion, but... if you need to implement it on that way, this is a possible solution:
import java.util.Scanner;
public class Recursion {
public static void main(String[] args) {
double number;
Scanner input = new Scanner(System.in);
System.out.println("Enter a value= ");
number = input.nextInt();
double result = 0;
double expectedValue = number;
int k = 0;
while (result < expectedValue) {
k++;
result = sum(k);
}
System.out.println(k
+ " is the term that should be added in order to reach "
+ number + " (" + sum(k) + ")");
}
public static double sum(double k) {
if (k == 1)
return 1 / 3;
else
return ((k / (2 * k + 1)) + sum(k - 1));
}
}