Issue with recursion - java

I am trying to do a questions in Java which involves taking a Lisp List and a integer, and multiplies all the items in the list by the integer but it has to use recursion. This is my code:
public static LispList<Integer> multipy(LispList<Integer> ls, int m){
LispList<Integer> ls1 = LispList.empty();
if(ls.isEmpty()){
return ls1;
}else{
ls1.cons(ls.head() * b);
}
return multipy(ls1, m)
}
My idea was to first create a empty list, ls1. I then use a base case where I check whether the original list - ls - is empty and if so, to return the new List, ls1. If it isnt empty, I then multiply all items by the integer and pass it into ls1. I then call the method again at the end.
However my issue is this wont work as it will create a new List ls1 each time, thus destroying the list already created. I thought about passing in ls1 into the recursive call but this dosent work either as it operates on ls1 and not ls as required. Is there a way around this or do I have to use a iterative method to do it?

multiply(ls.tail(),m) gets you a list which contains all the values of the tail of ls multiplied. To that list you only have to add the head of ls multiplied, which you seem to do with the cons() method. So, it would be something like:
public static LispList<Integer> multipy(LispList<Integer> ls, int m){
// No point making the else case if your
// last statement of the block is a return
if(ls.isEmpty()) return LispList.empty();
return multiply(ls.tail(),m).cons(ls.head()*m);
}
I'm assuming your LispList has a tail() method.

Related

How is a Java ArrayList modified when passed as parameter to function that returns void and modified in function? May be confused on pass-by-value

I have a block of Java code that modifies an ArrayList by passing the ArrayList into a method, modifying the list in the method, and returns void. I thought that Java's pass-by-value would cause the original ArrayList to not be modified. What am I misunderstanding?
public class Question {
public static void weaveLists(LinkedList<Integer> first, LinkedList<Integer> second, ArrayList<LinkedList<Integer>> results, LinkedList<Integer> prefix) {
/* One list is empty. Add the remainder to [a cloned] prefix and
* store result. */
if (first.size() == 0 || second.size() == 0) {
LinkedList<Integer> result = (LinkedList<Integer>) prefix.clone();
result.addAll(first);
result.addAll(second);
results.add(result);
return;
}
/* Recurse with head of first added to the prefix. Removing the
* head will damage first, so we’ll need to put it back where we
* found it afterwards. */
int headFirst = first.removeFirst();
prefix.addLast(headFirst);
weaveLists(first, second, results, prefix);
prefix.removeLast();
first.addFirst(headFirst);
/* Do the same thing with second, damaging and then restoring
* the list.*/
int headSecond = second.removeFirst();
prefix.addLast(headSecond);
weaveLists(first, second, results, prefix);
prefix.removeLast();
second.addFirst(headSecond);
}
public static ArrayList<LinkedList<Integer>> allSequences(TreeNode node) {
ArrayList<LinkedList<Integer>> result = new ArrayList<LinkedList<Integer>>();
if (node == null) {
result.add(new LinkedList<Integer>());
return result;
}
LinkedList<Integer> prefix = new LinkedList<Integer>();
prefix.add(node.data);
/* Recurse on left and right subtrees. */
ArrayList<LinkedList<Integer>> leftSeq = allSequences(node.left);
ArrayList<LinkedList<Integer>> rightSeq = allSequences(node.right);
/* Weave together each list from the left and right sides. */
for (LinkedList<Integer> left : leftSeq) {
for (LinkedList<Integer> right : rightSeq) {
//This is the part I don't understand
ArrayList<LinkedList<Integer>> weaved = new ArrayList<LinkedList<Integer>>();
weaveLists(left, right, weaved, prefix);
result.addAll(weaved);
}
}
return result;
}
}
I would expect that the weaved array would not be modified when the result.addAll(weaved) is called, but weaved array is modified after the call to weaveLists(), even though it returns void.
You create a weaved reference to an ArrayList object that stored in memory. When you call new operator then a new object allocated in the memory. Then you pass the reference weaved to the weaveLists() method.
This method have a reference result, but this is only a reference that refer to the same object in the memory, because only new operator allocate a new memory. So, the weaveLists() method modify your original ArrayList. It is a major feature that you should understand, I suggest you to read the difference between pass-by-value and pass-by-reference.
To answer the question in short - you are misunderstanding what does the pass-by-value mean in Java.
If you pass an object (list in this case) and manipulate it's elements without changing it's reference, it is the same object you passed, nothing changed on the object (list) itself, it has the same reference it had when passed to function, but changes do apply to any of the elements being manipulated.
Pass by value in this context only means that if you created a new instance of a given list within the function and then manipulated it - no changes would apply on original list, since that would be observed as a local variable, not the passed one.
Check top answers to this question, or just read some java basics related to pass-by-value. Use this blog, or any other that you might like more.

Creating an ArrayList inside a recursive method

I'm attempting to solve a problem that finds the amount of valid solutions to a chess problem and when the code is printed, it prints 92 arrays of an object PartialSolution I made that are the correct solutions. This is done recursively and I need to add these arrays to an array list but I can't figure out how.
Here's my code:
public ArrayList<PartialSolution> solve(PartialSolution sol ){
ArrayList<PartialSolution> solutions = new ArrayList<PartialSolution>();
int exam = sol.examine();
if(exam == PartialSolution.accept){
solutions.add(sol);
}
else if(exam != PartialSolution.abandon){
for(PartialSolution p : sol.extend()){
solve(p);
}
}
return solutions;
}
Define a variable in class and add your lists to that list instead of print.
Or make your solve method take a second argument as list and change return type from void to list. For the the first call give it an empty list and pass that list in every recursive call. At the end return that list
If you need the ArrayList just to store the solutions for later use then you should create the list out of the method like:
static ArrayList<PartialSolution> x = new ArrayList<PartialSolution>();
then just add the solution to the list when you print sol.

Update parameters of a list in a method: return list or not

I have a list of objects like the next class:
class A {
private String property1;
private String property2;
//Setters && Getters
}
So, after some operations I need to update the list with a default value with some logic like next:
listOfA.forEach(item -> {
item.setProperty1(findSomething());
}
This logic is repeated several times so I'm looking to export it to a method. So, my question is related to this method: Should I update the copy reference of the list with a void method, return it or create new list and update it?:
Option 1: Update the copy reference of the list
private void updateList(List<A> listOfA) {
listOfA.forEach(item -> {
item.setProperty1(findSomething());
}
}
Option 2: Return it
private List<A> updateList(List<A> listOfA) {
listOfA.forEach(item -> {
item.setProperty1(findSomething());
}
return listOfA;
}
Option 3: Create a new list from the other, update this and return it
private List<A> updateList(List<A> listOfA) {
List<A> newList = new ArrayList<>();
//Logic to copy listOfA in newList....
newList.forEach(item -> {
item.setProperty1(findSomething());
}
return newList ;
}
In the end it is very much personal opinion which option you prefer. There are however some considerations that might help you in the decision process:
The first and second option are virtually the same. Both operate on the List that is passed in as a parameter. The updating of the list does not create anything new. This would suggest option 1 as the solution to chose, as with only the signature alone (no additional documentation) option 2 might indicate that the returned list is a new List instance.
Returning the List as in option 2 and 3, has the advantage that you can execute further operations on that list, which make it changeable.
The last option employs defensive copy to actually create a new instance of the input List and operate on that list. While it is good practice to do so, it can have some side effects, that may be unwanted. With option 2 it is not required that the returned list is assigned to anything, as it is the same instance that was passed in as parameter. This is not the case of option 3. Here the result must be assigned, otherwise it becomes eligible for garbage collection.
Everything depends on the situation.
Option 1
This case is suitable when you do not need to use your list anywhere else. I mean that if other object has this list reference as member then this object will have this member modified too.
Option 2
This case seems like case 1 and you can use this method as case 1 but here you return your list. It brings some advantage in first case, you can use your method in chain of Stream API or Optionals:
private List<A> updateList(List<A> listOfA) {
List<A> newList = new ArrayList<>();
//Logic to copy listOfA in newList....
newList.forEach(item -> item.setProperty1(findSomething()));
return newList ;
}
public List<A> myMethod() {
List<A> myList = null;
// possible initialization of list
// ...
// here we update list. In the case when list is null then we do not modify it
return Optional.ofNullable(myList).map(this::updateList).orElse(null);
}
Option 3
In this case you copy array into another one. It make sense in the case when initial array should not be modified, for example it is field of some other class.
Method :3
when u r making a new list object it needs a certain memory in heap. And then you are just copy the content from your agrument list and update it and return the new list. Here creating a new list object takes an extra headache. No need for it.
Method :2
In this method no new list is created bt you return the same list. While java works on call by value (here values means values of the ref object). You can get the updated list on the calling method not need to return it. While u r returing an object u r increasing metadata of that method.
Method :1
It is the best approach. Here u are using the benefit of call by value (here values means values of the ref object). No unnecessary extra memory is occupied.
No unnecessary return. Thats the right approch.

How to retrieve objects values stored in a Java ArrayList

ArrayList<yellowPage> ob1 = new ArrayList<yellowPage>();
yellowPage thing = new yellowPage(100,100);
thing.calc(i,y,s3);
ob1.add(thing);
I stored some data in thing. How can I retrieve the value stored in ob1.thing?
If you know the index, you can do yellowPage
yellowPage yp = ob1.get(index);
Otherwise you need to iterate over the list.
Iterator<yellowPate> iter = ob1.iterator();
while(iter.hasNext())
{
yellowPage yp = iter.next();
yp.whateverYouwantGet();
}
Note: I just typed code here, there may be syntax errors.
int x=5;
int info=ob1.get(x).getInfo();
The above example will get whatever information you wanted from your yellow pages class (by using a getter method) at the 6th index (because 0 counts) of your array list ob1. This example assumes you want an integer from the yellow page. You will have to create a getter method and change the x to the index of the yellow page you want to retrieve information from.
An example getter method (which you should put in your yellow pages class) could look like this:
public int getInfo() { return z; }
In the above case z may be an instance variable in your yellow pages class, containing the information you're looking for. You will most probably have to change this to suit your own situation.
If you wanted to get information from all yellow pages stored in the array list then you will need to iterate through it as Chrandra Sekhar suggested
Use an Iterator object to do this.
ArrayList<yellowPage> ob1 = new ArrayList<yellowPage>();
yellowPage thing = new yellowPage(100,100);
thing.calc(i,y,s3);
ob1.add(thing);
yelloPage retrievedThing = null;
Iterator<yelloPage> i = ob1.iterator();
if(i.hasNext()){
retrievedThing = i.next();
}
You could have the data stored in thing (horribly named variable) simply returned from the calc method. That way you don't need to maintain state for prior calculations in subsequent calls. Otherwise you just need a getter type method on the YellowPage class.
public class YellowPage {
private int result;
public void calc(...) {
result = ...
}
public int getResult() {
return result;
}
}
Print the list and override toString method.
public String toString()
{
return (""+ a+b); //Here a and b are int fields declared in class
}
System.out.print(ob1);
Class ArrayList<E>
Syntax
ArrayList<Integer> list = new ArrayList<Integer>();
You replace "Integer" with the class that the list is of.
An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.
E represents an Element, which could be any class.
ensureCapacity is used to ensure that the list has enough capacity to take in the new elements. It's called internally every time you add a new item to the list. As the name suggests, ArrayList uses an Array to store the items. So when the array is initialized, it's given an arbitrary length, say 10. Now once you've added 10 items, if you go to add the 11th item, it'll crash because it exceeds the arrays capacity. Hence, ensureCapacity is called (internally) to ensure that there's enough space. So if you were adding the 11th element, the array size might be, say, doubled, to 20.

How to keep a "things done" count in a recursive algorithm in Java?

I have a recursive algorithm which steps through a string, character by character, and parses it to create a tree-like structure. I want to be able to keep track of the character index the parser is currently at (for error messages as much as anything else) but am not keen on implementing something like a tuple to handle multiple returned types.
I tried using an Integer type, declared outside the method and passed into the recursive method, but because it's final, recursive call increments are "forgotten" when I return. (Because the increment of the Integer value makes the passed-by-value object reference point at a new object)
Is there a way to get something similar to work which won't pollute my code?
Since you've already discovered the pseudo-mutable integer "hack," how about this option:
Does it make sense for you to make a separate Parser class? If you do this, you can store the current state in a member variable. You probably need to think about how you're going to handle any thread safety issues, and it might be overkill for this particular application, but it might work for you.
It's kind of a hack, but sometimes I use an AtomicInteger, which is mutable, to do things like this. I've also seen cases where an int[] of size 1 is passed in.
The current solution I am using is:
int[] counter = {0};
and then pass it to the recursive algorithm:
public List<Thing> doIt (String aString, int[] counter) { ... }
and when I want to increment it:
counter[0]++;
Not super elegant, but it works...
Integers are immutable, which means that when you pass it as an argument it creates a copy rather than a reference to the same item. (explanation).
To get the behavior you're looking for, you can write your own class which is like Integer only mutable. Then, just pass it to the recursive function, it is incremented within the recursion, and when you access it again after the recursion is over it will still maintain its new values.
Edit: Note that using an int[] array is a variation on this method... In Java, arrays are also passed by reference rather than copied like primitives or immutable classes.
You could just use a static int class variable that gets incremented each time your doIt method is called.
You could also do:
private int recurse (int i) {
if (someConditionkeepOnGoing) {
i = recurse(i+1);
}
return i;
}
To be honest I would recode the function to make it a linear algorithm that uses a loop. This way you have no chance of running out of heap space if you are stepping through an extremely large string. Also, you would not need to have a the extra parameter just to keep track of the count.
This also would probably have the result of making the algorithm faster because it does not need to make a function call for every character.
Unless of course there is a specific reason it needs to be recursive.
One possibility I can think of is to store the count in a member variable of the class. This of course assumes that the public doIt method is only called by a single thread.
Another option is to refactor the public method to call a private helper method. The private method takes the list as a parameter and returns the count. For example:
public List<Thing> doIt(String aString) {
List<Thing> list = new ArrayList<Thing>();
int count = doItHelper(aString, list, 0);
// ...
return list;
}
private int doItHelper(String aString, List<Thing> list, int count) {
// ...
// do something that updates count
count = doItHelper(aString, list, count);
// ...
return count;
}
This assumes that you can do the error handling in the public doIt method, since the count variable isn't actually passed back to the caller. If you need to do that, you could of course throw an exception:
public List<Thing> doIt(String aString) throws SomeCustomException {
List<Thing> list = new ArrayList<Thing>();
int count = doItHelper(aString, list, 0);
// ...
if (someErrorOccurred) {
throw new SomeCustomException("Error occurred at chracter index " + count, count);
}
return list;
}
It's difficult to know whether that will help without knowing more about how your algorithm actually works.

Categories

Resources