What it means ''depth()'' in java? - java

I am in a book with this code. I do not know which command the ''depth'' word is used for what purpose. I have found a few results but I do not understand what is still. I know java language but i am learning c ++ new.I wanted to know if there is something like this in Java.
if (depth() != otherStack.depth())
{
return false;
}
else
{
for (int n=0; n<depth(); n++)
{
if (!list[n].equals(otherStack.list[n]))
return false;
}
}

From the code snippet you posted, depth seems to be a method defined in the class whose instance is the otherStack variable. Here depth() probably returns the size of the stack.
The line depth() != otherStack.depth() compares the size of the Stack instance to the size of another Stack instance.

Related

Java - Content of List is lost in recursion

I'm currently programming on a little project (which is way to specific to explain here) and I got everything working except one part. I've got a List pZiegel by parameter which is modified in recursion. Because it didn't work, I did a little debugging and found the problem: At one point, the list contains exactly one number at the end of the method. Then, the program jumps one recursion depth back. And directly after that, it doesn't contains any numbers anymore. How did it lose the number? Lists as parameters work with pass-by-reference, so it shouldn't just reject it, right?
public void erstelleBaum (Tree pTree, List<Integer> pZiegel, List<Integer> pFugen, int tiefe) {
if (tiefe / n >= maxHoehe) {
System.out.println("hi");
mauerGefunden = true;
alleFugen = pFugen;
}
if (!mauerGefunden) {
pZiegel.toFirst();
while (pZiegel.hasAccess() && !mauerGefunden) {
boolean ziegelHinzufügen = false;
möglich = true;
aktZiegel = pZiegel.getContent();
// ...
if (möglich) {
// ...
pZiegel.remove();
if (pZiegel.isEmpty()) {
ziegelHinzufügen = true;
pZiegel = new List();
for (int i = 1; i <= n; i++) {
pZiegel.append(i);
}
}
// Recursion
erstelleBaum(neuesBlatt, pZiegel, neueFugen, neueTiefe);
// Here, it tells me that pZiegel is empty (at recursion depth 17)
if (ziegelHinzufügen) {
pZiegel.toFirst();
while (pZiegel.hasAccess()) {
pZiegel.remove();
}
pZiegel.append(aktZiegel);
}
else {
pZiegel.toFirst();
while (pZiegel.hasAccess() && pZiegel.getContent() < aktZiegel) {
pZiegel.next();
}
if (pZiegel.hasAccess()) {
pZiegel.insert(aktZiegel);
pZiegel.toFirst();
while (pZiegel.getContent() != aktZiegel) {
pZiegel.next();
}
}
else {
pZiegel.toLast();
pZiegel.append(aktZiegel);
pZiegel.toLast();
}
}
}
pZiegel.next();
}
}
// Here, pZiegel contained one number (at recursion depth 18)
}
I hope, the code isn't too messy. I tried to keep out the parts that doesn't involve pZiegel. And sorry, that the variables are named in german. I didn't want to change them for this post because I know I would forget to change something in the code.
Feel free to ask, if something is unclear.
I believe the pZiegel List reference is being lost at some point. You should check the pZiegel object ID (a number displayed when you inspect the object) to make sure it is the same List instance all over the recursions.
Notice that there's one part of your code that makes the pZiegel identifier reference a new List:
...
if (pZiegel.isEmpty()) {
ziegelHinzufügen = true;
pZiegel = new List(); // <---- this line
for (int i = 1; i <= n; i++) {
pZiegel.append(i);
}
}
...
I believe you are calling the 18th recursion with pZiegel referencing one list (maybe empty). Inside the 18th recursion that line is called and pZiegel starts referencing a new List (realize that the last List still exists and is referenceed by the pZiegiel identifier of the 17th recursion). On the last line of the 18th recursion call you believe you are inspecting the same pZiegiel List from the 17th recursion, but that's not the case.

How can I refactor a `for` loop?

Problem
I want to be able to split up a for loop into a method, then put the for the method in the for loop to make it easier to read. Below demonstrates this:
Example.java
for(int member = firstMember; member < arrayOfMembers.length; member++) {
[...] other code
}
Should be refactored to:
Solution Example:
private boolean eachMemberInList() {
return int member = firstMember; member < arrayOfMembers.length; member++);
}
public static void main(String[] args) {
for(eachMemberInList());
}
Is this possible?
No, you cannot return or otherwise manipulate a for loop as if it were an object in Java.
However, what you're attempting to do is unnecessary. You can use an array directly in an "enhanced" for loop, since Java 1.5.
for (int member : arrayOfMembers) { ... }
It is more concise than attempting to create a method to manipulate a for loop, and it is even more concise than the standard for loop you're attempting to replace.
What you're talking about is turning a for loop, into a while loop.
for (; true; )
is equivalent to
while (true)
So, you're solution could be viewed as
while (someFunctionIsTrue()) {}
Don't want to get into religious debates here, but generally, if you're iterating over an array of objects, you really do want to use a for lop. Not necessarily because it's any different than a while loop using your solution, but because it's idiomatic. When a developer (an experienced developer) sees a for loop, the fact that you chose a for loop tells them something. It says, hey, I'm iterating over the objects of a container. What a while loop says, is that there is some condition, and while that condition is true do something.
While loops and for loops are identically in capability. By using them idiomatically, you can communicate your code more concisely and clearly. For example:
int index = 0;
while (index < array.size) {
doSomethingWithArrayElement(array[index]);
index++;
}
This is not concise. The hanging variable declaration creates an extra line of code, as does the index++ at the end. When you do this:
for(int i = 0; i < array.size; i++) {
doSomething(array[i]);
}
This is very concise, and your use of a for loop... if used concistently like this, immediately tells a developer that all items of this container are going to have something done with them!
Now let's use the alternate example, where we have a function that returns a boolean. And this boolean tells the loop whether to continue or not. We could do something like this:
int index = 0;
for (; doSomethingWithArrayItem(array, index); index++){
}
boolean doSomethingWithArrayItem(array, index) {
//blah blah blah
if (index + 1 == array.size) return false;
return true;
}
This accomplishes what you want, but is difficult logic to follow. Let's say that you named your doSomething function something useful, like
incrementValueByTwo(item);
What do you think this function does? It's pretty clear right. Now, let's place this function in the for loop above:
int index = 0;
for (; incrementValueByTwo(array, index); index++){
}
How many values are we incrementing? Are we incrementing all the values of the array by 2? Some of them? The first one? Or perhaps none of them under certain circumstances? THIS IS VERY CONFUSING!!!! DON'T DO THIS!
I would rather do something like
String[] array = new String[10];
for(String variable : array){
doSomething(variable);
}
Or if you are using Java 8 then
Arrays.stream(array).forEach(memberOfArray -> doSomething(memberOfArray));
This is much more readable.

Objects: how to use the string declared before

I have the following code
public void makeBaby() {
String duplicate;
boolean full = false;
boolean same = false;
for (int i = 0; i < park.length; i++) {
if (park[i] == null) {
full = false;
} else if (i == park.length - 1 && park[i] != null) {
full = true;
}
if (i != park.length - 1) {
for (int j = 1; j < park.length; j++) {
if (park[i].name.equals(park[j].name)) {
same = true;
duplicate = park[i].name;
}
}
}
if (!full) {
System.out.println("The zoo is full. Cannot make any more babies");
} else if (!same) {
Animal duplicate = new Animal((float) 0.1 * park[i].mass,park[i].name, park[i].legs);
addAnimal(duplicate);
}
}
}
As may be able to see in the code, I have to see if the array called park is full and if not, I need to make a baby animal. but before that, I also need to check if there are 2 animals that have the same type(name).
But I am experiencing problems with the line
Animal duplicate = new Animal((float) 0.1 * park[i].mass,park[i].name, park[i].legs);
addAnimal(duplicate);
because the somehow java does not recognize the duplicate as the duplicate I set in the if statement above.
It is simply creating an animal called duplicate which is not what I want to do..
There are some other things that don't add up. For example:
full is declared as false. In the first if-statement:
if (park[i] == null) {
full = false;
which is already known.
If i am not mistaken:
(!full)
is read as false and is meant to be executed when full = true.
(full)
same goes for (!same)
I am no coding genius, so correct me if i'm wrong. :)
You have two variables each named duplicate, I suspect that this is confusing you.
You have variable
String duplicate;
and you have
Animal duplicate
What is your intention? they are different types.
I suspect you mean:
Animal theNewBaby ...
addAnimal(theNewBaby);
And somewhere you intend the name of the new baby to be the String you stored in duplicate. As we can't see your Animal() constructor we don't know.
You have multiple problems here... For one you have two duplicate variables... one String and one Animal. So depending on which parameter your addAnimal() method takes you might be grabbing the wrong duplicate.
Secondly, I don't believe your "Same" code check is going to work as you are looping through the same list twice. Unless you exclude the first found animal from your second j loop you are always going to find a match even when there is only one animal.
That might work for amoebas but not for elephants! :-)
You only have to rename your variable duplicate(for example sDuplicate with the type as prefix), there is no other way if you want to give addAnimal() the string duplicate you set in the if statement. And add to the if condition:
&& i!=j
then your duplicate check will work.

Initializing a variable in Recursion

My code is below:
public int workTimeSum(list of parameter){
int i=0,sum=0,flag=-1;
boolean b=true;
Stack<NonOverlapIntervals> str;
if(st.size()!=1){
b=recursiveCheck(non_overlap_list,st,Ioj);
if(b==false){
st.pop();
}
System.out.println("now size is:"+st.size());
}
str=(Stack<NonOverlapIntervals>) st.clone();
System.out.println("Stack is ss");
while(!str.empty()){
System.out.println(str.pop().self_id);
}
if(b || st.size()==1){
for(NonOverlapIntervals obj:non_overlap_list){
i++;
if(obj.id==ids){
if(st.size()!=1 && object_Present(st,obj)){
continue;
}
else{
st.push(obj);
sum=workTimeSum(non_overlap_list,obj,st,obj.self_id,i);
if(sum_max<sum)
sum_max=sum;
}
}
}
flag=1;
}
else{
return 0;
}
Above is a recursive code.
What you need to see in the above code is only sum, sum_max variable.
I am computing the sum and checking if it's greater than sum_max each time a sum is computed.
But as I have initialised sum_max to zero after each call my sum_max becomes 0;
The problem is eliminated if I declare sum_max as global variable.
But i am not allowed to use global variable.
I also tried passing sum_max a parameter of the recursive function but that won't work.
You can initialize the variable without needing a second method if you just check to see if it is null if so, initialize it and pass it to the next method (so it will be initialized)
//very basic endless example
public void myRecursiveMethod(Object var){
if (var==null){
var = new Object();
}
myRecusivemethod(var);
}
I think the answer lies in the way you have phrased the question. You misunderstand: you don't initialise a variable while you are recursing. You only initialise it once.
To do this, it may sometimes be helpful to create another method for the first step ("base case") of the recursion, which does the initialisation.
However, the code you posted doesn't actually match what you describe to be the case. In the code you posted, you don't initialise sum_max at all. So I'm confused.

Implementing edit distance method using recursion results in object heap error

private static int editDistance(ArrayList<String> s1, ArrayList<String> s2) {
if (s1.size()==0) {
return s2.size();
}
else if (s2.size()==0) {
return s1.size();
}
else {
String temp1 = s1.remove(s1.size()-1);
String temp2 = s2.remove(s2.size()-1);
if (temp1.equals(temp2)) {
return editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone());
} else {
s1.add(temp1);
int first = editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone())+1;
s2.add(temp2);
s1.remove(s1.size()-1);
int second = editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone())+1;
s2.remove(s2.size()-1);
int third = editDistance((ArrayList<String>)s1.clone(),(ArrayList<String>)s2.clone())+1;
if (first <= second && first <= third ) {
return first;
} else if (second <= first && second <= third) {
return second;
} else {
return third;
}
}
}
}
For example, the input can be ["div","table","tr","td","a"] and ["table","tr","td","a","strong"] and the corresponding output should be 2.
My problem is when either input list has a size too big, e.g., 40 strings in the list, the program will generate a can't reserve enough space for object heap error. The JVM parameters are -Xms512m -Xmx512m. Could my code need so much heap space? Or it is due to logical bugs in my code?
Edit: With or without cloning the list, this recursive approach does not seem to work either way. Could someone please help estimate the total heap memory it requires to work for me? I assume it would be shocking. Anyway, I guess I have to turn to the dynamic programming approach instead.
You clone() each ArrayList instance before each recursive call of your method. That essentially means that you get yet another copy of the whole list and its contents for each call - it can easily add-up to a very large amount of memory for large recursion depths.
You should consider using List#sublist() instead of clone(), or even adding parameters to your method to pass down indexes towards a single set of initial List objects.

Categories