Recursive methods Java - java

Recursion always has been something I have a hard time with. I have a test tomorrow and he said there will be some Recursion on the test so I want to be prepared.
The problem I am trying to do says this:
Given a class Rectangle with instance variables width and height, provide a recursive getArea() method. Construct a rectangle whose width is one less than the original and call its getArea method.
So I know that in recursion you end up calling the method inside itself with a simplified rendition. Like, I know somewhere in getArea(int n) I will have to call getArea(n - 1). I am just not sure what to do with width and height.
So I have this:
public int getArea()
{
if (width == 1) {
// Base case here. Not sure what to do for this.
return 1; // Maybe? I'm not sure.
} else {
Rectangle smallerRect = new Rectangle (width - 1);
int smallerArea = smallerRect.getArea();
return smallerArea + height + width;
}
}
Can anyone help me better understand recursion or maybe how to go about thinking through a recursive function? Thanks.

You've got the recursion itself right, with a base case and a recursive case, and a correct reduction of the parameter in the recursive call (except that, as the commenters have noted, you also need to specify the height of the new rectangle). It's only the geometry that needs fixing: height doesn't change during the recursion; what is the area of the base case rectangle, which has got width 1 and height height? And if you are told the area of the rectangle with width width - 1 and height height, how much extra area do you get by adding a strip of width 1 and height height?
For later use: while mathematically correct, this is a terrible way to compute the area of a rectangle, so please don't do this outside of exam/homework situations :-)

Something like this perhaps? It's basically just multiplying width by height with recursion...
public int getArea() {
return getArea(width);
}
private int getArea(int x) {
return x == 0 ? 0 : height + getArea(x-1);
}

public int getArea()
{
if (width == 1) {
// Base case
return height; // Area = width(1)*height
} else {
Rectangle smallerRect = new Rectangle (width - 1, height);
int smallerArea = smallerRect.getArea();
return smallerArea + height;
}
}

Related

Confusion regarding order of the parameter in constructor method [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
public class Wall {
private double width;
private double height;
public Wall() {}
public Wall(double width, double height) {
this.setHeight(height); // using method to set the required fields. //This method is called with unexpected behavior.
this.setWidth(width); // This is not getting called?
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
if (width <= 0) {
this.width = 0;
System.out.println("INVALID VALUE - The width of the wall is updated to :" + 0.0);
} else {
this.width = width;
System.out.println("The width of the wall is updated to :" + width);
}
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
if (height <= 0) {
this.height = 0;
System.out.println("INVALID VALUE - The width of the wall is updated to :" + 0.0);
} else {
this.height = height;
System.out.println("The height of the wall is updated to :" + height);
}
}
public double getArea() {
return width * height;
}
}
//OUTPUT
The width of the wall is updated to :10.0 \\ Expected
INVALID VALUE - The width of the wall is updated to :0.0 \\ not expected
//OUTPUT when parameter order in constructor is reversed
INVALID VALUE - The width of the wall is updated to :0.0 \\expected
The height of the wall is updated to :10.0 \\expected
The goal was to avoid code repetition and I chose to use the setter method in constructor. Also assuming since I am using methods and providing appropriate parameters, the order of the parameter should not matter.
I am not sure if it is supposed to work that way. I see that the method is being called with unexpected behavior.
Few doubts I have regarding the above
Not all methods are getting called in the constructor
Can these setter methods be static and perform operation on the object being created?
What would be the right way to do this?
Thank you
I see that the method is being called with unexpected behavior.
setHeight() actually performs as expected but it is not implemented as you'd expect it. You probably copied it from setWidth() and forgot to change the message so it would print "INVALID VALUE - The width of the wall is updated to : xxx".
the order of the parameter should not matter
The order in which you define the parameters doesn't matter from a technical point of view (unless you have a vargs parameter which needs to be last). However the order of definition leads to the requirement of providing values in the same order when calling the constructor.
Example: Wall(double width, double height) defines the 1st parameter is width and the 2nd is height.
Assume the following:
double width = 5.0;
double height = 7.0;
Wall w = new Wall(height, width);
Here, the names of the parameters don't matter but order does, i.e. w now has a width of 7 and a height of 5 even though the parameters were named otherwise.
What shouldn't matter in most cases is the order in which you call the setters inside the constructor - as long as they're independent.
This means the following 2 should be equivalent:
public Wall(double width, double height) {
this.setHeight(height);
this.setWidth(width);
}
public Wall(double width, double height) {
this.setWidth(width);
this.setHeight(height);
}
When would order matter? If setters were depending on it - not a good style though. Suppose setHeight() would check that height > width. Now if you'd not call setWidth() first setHeight() might behave differently. However, I repeat: this it not good style and should be avoided!
Not all methods are getting called in the constructor
Not sure what you're referring to but constructors don't have to call any method nor do you have to call all the setters there. It really depends on what you want to achieve.
Use constructors for mandatory parameters and setters for mutable ones (and potentially optional). Mutable parameters are those that could be changed after constructing an object, immutable ones should not change - there shouldn't be any setter for those (ideally declare those final and the compiler will complain about setters for those).
Summary:
mandatory + immutable parameters: use constructor only
mandatory + mutable parameters: use constructor which can call setters
optional + mutable parameters: use setters
optional + immutable parameters: use constructor only, potentially via constructor overloads
Can these setter methods be static and perform operation on the object being created?
No, setters should never be static because you'd need to pass the object anyway and thus it's cleaner to just have the setters there.
However, a constructor can call static methods if necessary. Suppose you have a condition to check that width < height which you'd want to call in the constructor and the setters. This could then look like this (simplified and lacking a lot of best practices to keep things simple):
//example of constructor calling the static method
public Wall(double width, double height) {
//check the condition on the input parameters
if( !checkCondition(width, height) ) {
throw new IllegalArgumentException("width >= height");
}
this.setHeight(height);
this.setWidth(width);
}
//example of setter calling the static method
public void setWidth(double width) {
//only set if the condition is met
if(checkCondition(width, this.height) {
//rest of your code
} else {
System.err.println("width would be < height, thus not updating width");
}
}
private static boolean checkCondition(double width, double height) {
return width < height;
}

finding the other two points of a Perfect Right Triangle

I am writing code that is meant to use one given point of a perfect right triangle to find the remaining two. We assume for this exercise that it is a triangle like so: righttriangle
The first bit of code uses the Point2D class to establish the bottom left point like so:
public Triangle(Point2D.Double bottomLeftPoint, double height, double base){
this.base = base;
this.height = height;
this.bottomLeftPoint = bottomLeftPoint;
}
public Point2D.Double getBottomLeftTrianglePoint() {
return this.bottomLeftPoint;
}
I know that mathematically, the top point of the triangle would have the same x value, but would have the y value added by the height. Also the bottom right point would have the same y value but the x value added by the base.
My question is for method purposes, how would I structure that?
Would it be something like:
public Point2D.Double getTopTrianglePoint() {
return this.bottomLeftPoint(x, y + this.height);
}
public Point2D.Double getBottomRightTrianglePoint() {
return this.bottomLeftPoint(x + this.base, y);
}
For further info, I have a separate class that is meant to test the methods with with a test triangle:
public class TriangleTest {
private Triangle triangle01;
public TriangleTest() {
this.triangle01 = new Triangle(new Point2D.Double(1, 2), 5, 3);
}
}
Any help is appreciated. Thanks!
return this.bottomLeftPoint(x, y + this.height);
Break this down, then you'll notice this doesn't make sense. this.bottomLeftPoint is a variable of type Point2D.Double. You then.. try to treat this as a method somehow. It's not. This doesn't work.
You want to create an entirely new Point2D.Double. new Point2.Double(x, y) as per usual; Thus:
return new Point2D.Double(x, y + this.height);
Except, of course, if you try this, the compiler will tell you this doesn't work either; the compiler has no idea what x means. So, what do you intend to use there? Clearly it's the x coordinate of the Point2D.Double object referenced by your this.bottomLeftPoint field. Which has a .getX() method. So:
return new Point2D.Double(bottomLeftPoint.getX(), bottomLeftPoint.getY() + height);

Java: Iteration to find a coordinate point that hasn't been used?

I am using the following method to try to find a point (coordinate) that hasn't been previously used, and isn't within the bounds of items that have previously used and coordinates.
The way it works is I am rendering "bases" (RTS top-down game), and I am creating two random variable locations for x and y. I pass these, along with the bases texture, into the following method. The method loops through a list of rectangles that are the rectangles of each previously rendered base. If the point is within any of the rectangles, the method is called again using a different set of coordinates. It does this until it finds a set that isn't within a rectangle. It then adds a new rectangle to the list at these coordinates, and returns them so the game can render a new base.
However, the bases still overlap.
Here is the method:
private Point getCoords(int x, int y, Texture t){
for (int i=bases.size()-1; i> -1; i--) {
if (bases.get(i).contains(new Point(x,y))){
x = new Random().nextInt(map.getWidth() * map.getTileWidth());
y = new Random().nextInt(map.getHeight() * map.getTileHeight());
getCoords(x, y, t);
}
}
bases.add(new Rectangle(x,y,t.getImage().getWidth(), t.getImage().getHeight()));
return new Point(x, y);
}
And here is where it is being called:
switch(ran){
default:
int x = new Random().nextInt(map.getWidth() * map.getTileWidth());
int y = new Random().nextInt(map.getHeight() * map.getTileHeight());
Point p = getCoords(x, y, temp);
map.generateBase("air", p.x, p.y);
break;
}
Any ideas what is wrong here?
Thanks
There are several problems:
Your algorithm might be overwritting good coordinates (free ones) with wrong coordinates, you dont have any condition to exit the loop/recursion if you find a good place
You are checking for if rectangle contains the point, but later you are adding a rectanble, so it may not contain the point, but the rectangle created later may collide
try this
private Point getCoords(int x, int y, Texture t){
boolean found = false;
final int width = map.getTileWidth();
final int height = map.getTileHeight();
while(!found) {
x = new Random().nextInt(map.getWidth() * width);
y = new Random().nextInt(map.getHeight() * height);
for (int i=bases.size()-1; i> -1; i--) {
if (!bases.get(i).intersects(new Rectanble(x,y, width, height))){
found = true;
} else found = false;
}
}
bases.add(new Rectangle(x,y,t.getImage().getWidth(), t.getImage().getHeight()));
return new Point(x, y);
}
*** EDIT: Im not sure if I had to use TileWidth and TileHeight or image width and image height for width and height :D
int x = new Random().nextInt(map.getWidth() * map.getTileHeight());
Maybe a bad copy paste. It may be :
int x = new Random().nextInt(map.getWidth() * map.getTileWidth());
In both codes :-D
Okay so after some playing around, I found the issue is the rectangles that are saved are saved with a fixed location which means as the map moves, the rectangles don't. The fix is to loop through each bases and get the base's map position, rather than screen position, and check against this. Also, I found i was checking for a point in a rectangle, which may be outside the rectangle but leaves my bases overlapping still. So i now check for rectangle-rectangle collision instead

How to rotate an asterisk trapezoid in java?

In a school assignment we have to draw a trapezoid with asterisk in java. The constructor is like
Trapezoid(int tWidth, int bWidth, char signA, char signB, int margin)
tWidth: is the top width, bWidth: bottom width, signA: foreground sign, signB: background sign and margin: the margin (left and right) of the bWidth.
my main() class looks like this:
Trapezoid t = new Trapezoid(3, 9, '*', '-', 2);
t.printTrapezoid();
then it should look like this:
-----***-----
----*****----
---*******---
--*********--
the printTrapezoid() method looks like this:
int width = 2* margin + bWidth;
int length = (width - tWidth) / 2;
while (tWidth <= bWidth) {
printChar(signB, length);
printChar(signA, tWidth);
printChar(signB, length);
System.out.println();
tWidth++;
}
The printChar() method looks like:
printChar(char signB, int length) {
for (int i = 0; i < length; i++) {
System.out.print(signB);
}
}
So. This works fine for me. But i think there are some other and better solutions for that. The next exercise is to rotate this trapezoid just with t.rotate() in the main() class. So that it looks like:
--*********--
---*******---
----*****----
-----***-----
I have no idea how to do it. Can anybody give me a hint?
Please, I don't want the solution here. Just a hint how i can solve it. Maybe it is better to refactor the draw method? I don't know...
You haven't shown us the whole Trapezoid class, but I'm guessing that it has a field tWidth that you set in your constructor.
If that's the case, your printTrapezoid method shouldn't be changing it. That field, the "top width", is a property of the trapezoid that shouldn't change when you print it out. So in printTrapezoid, you should declare a local variable that's something like
int currentWidth = tWidth;
and then the method should modify this local variable, not the tWidth field.
Once you've done that, it should be very simple to see how to print the upside-down trapezoid, by making currentWidth become the same values in the reverse order.
EDIT: If rotate is supposed to change the properties of the trapezoid, rather than printing an upside-down trapezoid, then that should be easy too since you've fixed printTrapezoid not to change tWidth and bWidth, so now you can do what you need to do to change them (by swapping the values).

Check if rectangle contains another rectangle with specific distance between borders

I am trying to write small program to check if one rectangle contains second rectangle and distance betwwen their borders should be less than some specific number like 100 or 50.
When I use Rectangle.contains method it doesnt care about about distnce between borders of both rectangle.
Is there any way this can be achieved?
You could use the contains(Rectancle r) method twice: first to check if the inner rectangle is inside the outer rectangle at all, then temporarily enlarge the inner rectangle by half the threshold into every direction and make the same check again. This time it shouldn't be inside the outer rectangle anymore. So basically something like this:
//Rectangle outer; // Do some proper setup for these two
//Rectangle inner;
int limit = 50;
boolean containsWithinLimits = outer.contains(inner);
inner.setLocation(inner.getX()-limit/2, inner.getY()-limit/2);
inner.setSize(inner.getWidth()+limit, inner.getHeight()+limit);
boolean containsWithinLimits = containsWithinLimits && !outer.contains(inner);
// Now reset the bounds:
inner.setLocation(inner.getX()+limit/2, inner.getY()+limit/2);
inner.setSize(inner.getWidth()-limit, inner.getHeight()-limit);
example code etc?
Even so, you'll want to do the following:
unless im mistaken.
pseudo code:
rectA = outside, rectB = inside
if rectB.left - rectA.left < x then distance is ok else do something
if rectB.top - rectA.top < y then distance is ok else do something
etc etc
If the rectangles are orthogonal, and I assume that you have called contains(Rectangle rect). Then you only have to do extra comparisons:
inside.x - outside.x >= LEFT_BORDER &&
outside.x + outside.width - inside.x - inside.width >= RIGHT_BORDER &&
inside.y - outside.y >= TOP_BORDER &&
outside.y + outside.height - inside.y - inside.height >= BOTTOM_BORDER
LEFT_BORDER, RIGHT_BORDER, TOP_BORDER, BOTTOM_BORDER are for you to define.
In Rectangle2d ,we are having
boolean contains(double x, double y)
--- Tests if a specified coordinate is inside the boundary of this Rectangle2D.
boolean contains(double x, double y, double w, double h)
--- Tests if the interior of this Rectangle2D entirely contains the specified set of rectangular coordinates.
So it is not possible to check about the distance to my knowledge...

Categories

Resources