public class MultiplyViaRecursion{
public static void main(String[] args){
System.out.println("8 * 9 == " + multiply(8, 9));
System.out.println("6 * 0 == " + multiply(6, 0));
System.out.println("0 * 6 == " + multiply(0, 6));
System.out.println("7 * -6 == " + multiply(7, -6));
}
public static int multiply(int x, int y){
int result = 0;
if(y > 0)
return result = (x + multiply(x, (y-1)));
if(y == 0)
return result;
if(y < 0)
return result = -multiply(x, -y);
return result;
}
}
My question is very simple and basic, why after each "if" the "return" still cannot pass the compilation, error shows missing return.
To put it simply: the Java compiler isn't that smart. It can't deduce that one of your three if statements must evaluate to true. And since the compiler believes there is a chance all the if conditions can fail, it thinks it's possible to go beyond the if blocks, at which point there is no return statement.
Instead, try using an if else block, like so.
public static int multiply(int x, int y) {
int result = 0;
if (y > 0)
return result = (x + multiply(x, (y - 1)));
else if (y == 0)
return result;
else
return result = -multiply(x, -y);
}
Because the compiler cannot guess that your three IFs cover all the cases.
If you want to simplify the code, you can remove the last IF that is unnecessary :
public static int multiply(int x, int y){
int result = 0;
if(y > 0)
return result = (x + multiply(x, (y-1)));
if(y == 0)
return result;
return result = -multiply(x, -y);
}
By the way, you can also remove the result variable :
public static int multiply(int x, int y){
if(y > 0)
return (x + multiply(x, (y-1)));
if(y == 0)
return 0;
return -multiply(x, -y);
}
Related
This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
When should I use "this" in a class?
(17 answers)
Closed 11 months ago.
I'm trying to make a checkers game as practice for personal reasons, as I am somewhat newer to Java and am trying to learn.
In class Board, I'm trying to call a method that requires a Board type as input, to see which pieces a specific piece could possibly jump.
Here's Board:
public class Board {
private Piece[][] board;
public Board(){
board = new Piece[8][8];
}
public Piece pieceAtLocation(int x, int y){
return board[x][y];
}
public boolean movePiece(int startX, int startY, int newX, int newY, String movementType){
Piece temp = board[startX][startY];
if(movementType.equals("move")){
board[newX][newY] = temp;
board[startX][startY] = null;
return true;
} else if(movementType.equals("jump")){
int[][] possibleSpaces = temp.jumpableSpaces(this);
}
return false;
}
}
Here's the Piece class it's calling from
public class Piece {
private boolean isKinged;
private boolean teamSided;
private int x;
private int y;
public Piece(boolean teamSided, int x, int y){
this.isKinged = false;
this.teamSided = teamSided;
this.x = x;
this.y = y;
}
public boolean team(){
return teamSided;
}
public boolean kinged(){
return isKinged;
}
public int[][] jumpableSpaces(Board board){
int[][] jumpTo = new int[4][2];
if(x - 2 >= 0 && y + 2 < 8){
if(board.pieceAtLocation(x - 2, y + 2) == null && board.pieceAtLocation(x - 1, y + 1).team() != teamSided){
jumpTo[0][0] = x - 2;
jumpTo[0][1] = y + 2;
} else{
jumpTo[0][0] = -1;
jumpTo[0][1] = -1;
}
}
if(x + 2 < 8 && y + 2 < 8){
if(board.pieceAtLocation(x + 2, y + 2) == null && board.pieceAtLocation(x + 1, y + 1).team() != teamSided){
jumpTo[1][0] = x + 2;
jumpTo[1][1] = y + 2;
} else{
jumpTo[1][0] = -1;
jumpTo[1][1] = -1;
}
}
if(isKinged){
if(x - 2 >= 0 && y - 2 >= 0){
if(board.pieceAtLocation(x - 2, y - 2) == null && board.pieceAtLocation(x - 1, y - 1).team() != teamSided){
jumpTo[2][0] = x - 2;
jumpTo[2][1] = y - 2;
}
}
if(x - 2 >= 0 && y + 2 < 8){
if(board.pieceAtLocation(x - 2, y + 2) == null && board.pieceAtLoaction(x - 1, y + 1).team() != teamSided){
jumpTo[3][0] = x - 2;
jumpTo[3][1] = y + 2;
}
}
} else{
jumpTo[2][0] = -1;
jumpTo[2][1] = -1;
jumpTo[3][0] = -1;
jumpTo[3][1] = -1;
}
return jumpTo;
}
}
My question involves line 19 of Board. Is it possible to leave it as is and have it input itself using "this" or will I have to do something else? I'm not yet fully understanding of what "this" means, as I heard about its use in the constructors from a friend.
You can absolutely pass 'this' as a parameter to an internal function. 'This' basically refers to the specific instance of the object, so any value that is stored within it will be passed along as well.
I'd like to change this exponentiation method (n is the exponent):
public static double exponentiate(double x, int n) {
counter++;
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
return x * exponentiate(x, n - 1);
}
}
I'd like to change the method to make it more efficient, so the method is not opened n times but maximum (n/2+1) times WITHOUT using the class MATH.
So far I came up with this code:
public static double exponentiate(double x, int n) {
counter++;
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
if (n % 2 == 0) {
n = n-(n-1);
} else {
n = ((n-1) / 2) + n;
}
return ((x * x) * exponentiate(x, n - (n / 2)));
}
}
But somehow it only works for odd n, not vor even n.
Can somebody help?
Thanks!
I think you can optimize the above method to run for O(logn) by calculating exponentiate(x,n/2) once and using it.
Something like this:-
public static double exponentiate(double x, int n)
{
int temp;
if(n == 0)
return 1;
temp = exponentiate(x, n/2);
if (n%2 == 0)
return temp*temp;
else
return x*temp*temp;
}
Hope this helps!
I don't know if this is the solution you search but this is an example of an algorithm that perform exponentiation in O(log(n)) time
public static double exponentiate(double x, int n) {
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
return ((n % 2 == 0) ? 1 : x) * exponentiate(x * x, n / 2);
}
}
Write a method named consecutive that accepts three integers as parameters and returns true if they are three consecutive numbers; that is, if the numbers can be arranged into an order such that there is some integer k such that the parameters' values are k, k+1, and k+2. Your method should return false if the integers are not consecutive. Note that order is not significant; your method should return the same result for the same three integers passed in any order.
For example, the calls consecutive(1, 2, 3), consecutive(3, 2, 4), and consecutive(-10, -8, -9) would return true. The calls consecutive(3, 5, 7), consecutive(1, 2, 2), and consecutive(7, 7, 9) would return false.
This is what I have so far and keep getting infinite loop error and skipped tests
public boolean consecutive(int x, int y, int z) {
Scanner kb = new Scanner(System.in);
x = kb.nextInt();
y = kb.nextInt();
z = kb.nextInt();
if (((x < y && x < z) && (y < z && ((y - x) == 1) && ((z - x) == 2)))
||((z < y && ((z - x) == 1) && ((y - x) == 2))))
{
return true;
} else if (((y < x && y < z)&& (x < z && ((x - y) == 1) && ((z - y) == 2)))
|| ((z < x && ((z - y) == 1) && ((x - y) == 2))))
{
return true;
} else if (((z < x && z < y)&& (y < x && ((y - z) == 1) && ((x - z) == 2)))
||((x < y && ((x - z) == 1) && ((y - z) == 2))))
{
return true;
} else {
return false;
}
What you have there is serious overkill and pretty much unreadable to anyone who hasn't spent a large proportion of their career in C :-)
You should always strive for readability (and hence maintainability) first, reverting to less readable code only when absolutely necessary. Even if you do revert, you should then document why and what you've done so the next poor soul that has to maintain your code won't be cursing your name.
For this specific case, what you are attempting can be achieved in much simpler code such as the following (pseudo-code):
def areConsecutive(a, b, c):
if a > b: swap a, b
if b > c: swap b, c
if a > b: swap a, b
return (b - a == 1) and (c - b == 1)
The three if statements are simply an unrolled bubble sort to ensure a, b and c are in ascending order, then you simply check to ensure the difference between them is one in both cases.
There's no need to put them into a list or array to sort them since sorting three items is relatively easy (the swap can be done with int t = a; a = b; b = t;).
In terms of Java code (once you've moved the input to outside the function where it belongs), you'd end up with something like:
bool areConsecutive(int a, int b, int c) {
int t;
if (a > b) { t = a; a = b; b = t; }
if (b > c) { t = b; b = c; c = t; }
if (a > b) { t = a; a = b; b = t; }
return (b - a = 1) && (c - b == 1);
}
When you are passing value why using scanner?
Remove those lines and its working. You can use another logic to determine consecutive numbers.
public boolean consecutive(int x, int y, int z) {
if (((x < y && x < z) && (y < z && ((y - x) == 1) && ((z - x) == 2))) ||((z < y && ((z - x) == 1) && ((y - x) == 2)))) {
return true;
} else if (((y < x && y < z)&& (x < z && ((x - y) == 1) && ((z - y) == 2))) ||
((z < x && ((z - y) == 1) && ((x - y) == 2)))){
return true;
} else if (((z < x && z < y)&& (y < x && ((y - z) == 1) && ((x - z) == 2))) ||((x < y && ((x - z) == 1) && ((y - z) == 2)))){
return true;
} else
return false;
}
Just Remove these code:
Scanner kb = new Scanner(System.in);
x = kb.nextInt();
y = kb.nextInt();
z = kb.nextInt();
Or use Like this:
public class test{
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
x = kb.nextInt();
y = kb.nextInt();
z = kb.nextInt();
System.out.println("Result:" + consecutive(x, y, z));
}
public static boolean consecutive(int x, int y, int z) {
if (((x < y && x < z) && (y < z && ((y - x) == 1) && ((z - x) == 2))) || ((z < y && ((z - x) == 1) && ((y - x) == 2)))) {
return true;
} else if (((y < x && y < z) && (x < z && ((x - y) == 1) && ((z - y) == 2)))
|| ((z < x && ((z - y) == 1) && ((x - y) == 2)))) {
return true;
} else if (((z < x && z < y) && (y < x && ((y - z) == 1) && ((x - z) == 2))) || ((x < y && ((x - z) == 1) && ((y - z) == 2)))) {
return true;
} else {
return false;
}
}
}
Create a list with the numbers, sort it and do de diference between the elements:
public static boolean myConsecutive(int x, int y, int z) {
final List<Integer> list = new ArrayList<>();
list.add(x);
list.add(y);
list.add(z);
Collections.sort(list);
return (list.get(2) - list.get(1) == 1 && list.get(1) - list.get(0) == 1);
}
The consecutive method is passed with three values , then why you are reading from the console.
create an array with the size of 3 elements.
Sort the arrays using Arrays.Sort method
Check the difference between the second and the first number is 1 and difference between Third and the second number is 1.
Code :
public boolean consecutive(int x, int y, int z) {
int [] numbers = new int [3];
numbers[0] = x;
numbers[1] = y;
numbers[2] = z;
Arrays.sort(numbers);
boolean isConsecutive = (numbers[1]==numbers[0]+1)&&(numbers[2]==numbers[1]+1);
return isConsecutive;
}
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 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.