I want to convert the recursive function given below:
LinkedList i=a; //a contains the nodes which are adjacent to the last element of g
for(String i1: i )
{
if(g.contains(i1) || i1.equals("o"))
{ continue; }
g.addLast(i1);
func(g);
g.removeLast();
}
I want to convert the above program to an iterative one. Can someone help
LinkedList i=a; //a contains the nodes which are adjacent to the last element of g
for(String i1: i )
{
if(g.contains(i1) || i1.equals("o"))
{ continue; }
g.addLast(i1);
func(g);
g.removeLast();
}
So walking through this it appears as though the steps are as follows:
1) Check for existence of current String or if it equals "o"
2a) If yes continue
2b) else put current string at end of list.
3) repeat steps 1->2
4) remove the last element of the list
If I were to make the code as simple as possible given those steps it would look like so:
func(LinkedList ll)
{
Set set = new HashSet(ll); //removes all duplicates
if(set.contains("o") { set.remove("o") ;} //these are strings so that works
LinkedList newLL = new LinkedList(set); //order still retained
newLL.poll(); //remove last element
}
If I understand correctly your code, it finds all the available paths, right ?
The main 2 issues I see in your 2nd code are :
In the recursive version, you handle the path with currentNode by calling func, then remove currentNode. In the iterative version, you put visitedNodes in the stack "to be handled", and then alter visitedNodes before it was handled !
Related issue : you're always stacking over and over the same visitedNodes
So some solutions would be to put in the stack a copy of visitedNodes + the element currentNode.
visitedNodes will not be altered this way
I can do a bit of code if needed
Related
I have an ArrayList, which contains game objects sorted by their 'Z' (float) position from lower to higher. I'm not sure if ArrayList is the best choice for it but I have come up with such a solution to find an index of insertion in a complexity faster than linear (worst case):
GameObject go = new GameObject();
int index = 0;
int start = 0, end = displayList.size(); // displayList is the ArrayList
while(end - start > 0)
{
index = (start + end) / 2;
if(go.depthZ >= displayList.get(index).depthZ)
start = index + 1;
else if(go.depthZ < displayList.get(index).depthZ)
end = index - 1;
}
while(index > 0 && go.depthZ < displayList.get(index).depthZ)
index--;
while(index < displayList.size() && go.depthZ >= displayList.get(index).depthZ)
index++;
The catch is that the element has to be inserted in a specific place in the chain of elements with equal value of depthZ - at the end of this chain. That's why I need 2 additional while loops after the binary search which I assume aren't too expensive becouse binary search gives me some approximation of this place.
Still I'm wondering if there's some better solution or some known algorithms for such problem which I haven't heard of? Maybe using different data structure than ArrayList? At the moment I ignore the worst case insertion O(n) (inserting at the begining or middle) becouse using a normal List I wouldn't be able to find an index to insert using method above.
You should try to use balanced search tree (red-black tree for example) instead of array. First you can try to use TreeMap witch uses a red-black tree inside to see if it's satisfy your requirements. Possible implementation:
Map<Float, List<Object>> map = new TreeMap<Float, List<Object>>(){
#Override
public List<Object> get(Object key) {
List<Object> list = super.get(key);
if (list == null) {
list = new ArrayList<Object>();
put((Float) key, list);
}
return list;
}
};
Example of usage:
map.get(0.5f).add("hello");
map.get(0.5f).add("world");
map.get(0.6f).add("!");
System.out.println(map);
One way to do it would to do a halving search, where the first search is half way thru your list (list.size()/2), then for the next one you can do half of that, and so on. With this exponential method, instead of having to do 4096 searches when you have 4096 objects, you only need 12 searches
sorry for the complete disregard for technical terms, I am not the best at terms :P
Unless I overlook something, your approach is essentially correct (but there's an error, see below), in the sense that your first while tries to compute the insert-index such that it will be placed after all lower OR EQUAL Z: there's correctly an equal sign in your first test (updating "start" if it yields TRUE).
Then, of course, there's no need to worry anymore about its position among equals. However, your follow-up while destroys this nice situation: the test in the first follow-up while yields always TRUE (one time) and so you move back; and then you need the second follow-up while to undo that. So, you should remove BOTH follow-up whiles and you're done...
However, there's a little problem with your first while, such that it doesn't always exactly do what the purpose is. I guess that the faulty outcomes triggered you to implement the follow-up whiles to "repair" that.
Here's the issue in your while. Suppose you have a try-index (start+end)/2 that points to a larger Z, but the one just before it has value Z. You then get into your second test (elseif) and set "end" to the position where that Z-value resides. Finally you wind up with precisely that position.
The remedy is simple: in your elseif assignment, put "end = index" (without the -1). Final remark: the test in the elseif is unnecessary, just else is sufficient.
So, all in all you get
GameObject go = new GameObject();
int index = 0;
int start = 0, end = displayList.size(); // displayList is the ArrayList
while(end - start > 0)
{
index = (start + end) / 2;
if(go.depthZ >= displayList.get(index).depthZ)
start = index + 1;
else
end = index;
}
(I hope I haven't overlooked something trivial...)
Add 1 to the least significant byte of the key (with carry); binary search for that insert position; and insert it there.
Your binary search has to be so constructed as to end at the leftmost of a sequence of duplicates, but this is trivial given an understanding of the various Binary search algorithms.
I need to find the previous and next valid element in an arraylist. For example my arraylist contain
specialcharArray = ["dummy", "dummy",1.xml, "dummy","dummy","2.xml, "dummy","dummy","dummy","dummy", "3.xml"]
Let us consider am in 3.xml and i need to go to 2.xml. How to find the index of previous xml and suggest some idea.
My code:
if(!specialcharArray .get(arrayindex).equals("dummy")) {
arrayindex = arrayindex-1;
}
But this logic works only for one dummy but i dont know how many dummy element available. Any idea post here.
Try:
while(index >= 0 && "dummy".equals(specialcharArray.get(index))) { index--; }
.. after, check index != -1 to make sure it found one.
Im trying to implement the Breadth-First algorithm for 8 puzzle game. I know that it is not a new case and theres a bunch of solutions on web, but I want to make it on my way of thinking.
This code already finds the node result, which is
123
456
780
But it takes 350,000 steps to do it!
Any thoughts would be appreciated!
=)
//This method receives a Collection of `Nodo` objects, each one will be checked and compare with the finalGoal
public void percorreNodos(Collection<Nodo> nodosBase)
{
//In this class a have an array that has all the IDs os nodes that already has been checked
//The ID of a Node, is the representation: 123456780, 354126870 , etc..
System.out.println("idsPercorrido.size() = " + idsPercorridos.size());
//Check if the collection nodosBase contains the finalGoal
Iterator<Nodo> iterator = nodosBase.iterator();
while( iterator.hasNext() )
{
Nodo nodoBase = (Nodo) iterator.next();
//If this current node has already been checked, we dont have to check it again
idsPercorridos.add( nodoBase.getId() );
//Just print the node (sysout)
nodoBase.print();
contPassos++;
System.out.println( "\n" + contPassos + " STEPS(number of nodes checked)..." );
//Check if this node is the final goal
if( nodoBase.isObjetivoFinal() )
{
//set the variable indicating that the result has been found
encontrouObjetivo = true;
System.out.println( "Resultado alcancado EM " + contPassos + " PASSOS..." );
nodoBase.print();
break;
}
}
// Now that we know that no one Node of nosoBase collection is the final goal, we are going to generate the next children to be checked, and call this function recursively
//Just confirm that we didnt find the goal
if(encontrouObjetivo == false)
{
//Creates the next frontier
Collection<Nodo> novaFronteira = new HashSet<Nodo>();
for(Nodo nodoPai : nodosBase)
{
//Generate each Node its childrens and add to a collection called "novaFronteira"
Collection<Nodo> filhos = nodoPai.gerarFilhos();
for(Nodo filho : filhos)
{
//idsPercorridos is a collection<String> which contains all the nodes ids that we checked, we dont want to check a node more than one time !
if( idsPercorridos.contains( filho.getId() ) == false )
{
novaFronteira.add( filho );
}
}
}
this.percorreNodos( novaFronteira );
}
}
You could make sure you don't add duplicate elements to novaFronteira.
There's nothing preventing this code:
for(Nodo nodoPai : nodosBase)
{
Collection<Nodo> filhos = nodoPai.gerarFilhos();
for(Nodo filho : filhos)
{
if( idsPercorridos.contains( filho.getId() ) == false )
{
novaFronteira.add( filho );
}
}
}
From adding many duplicate nodes to novaFronteira.
If you were to add to idsPercorridos inside the if-statement, that would prevent this from happening, and result in less steps, although, depending on exactly what your data and data structures looks like, the added running time of this call may actually make it take longer than it did originally.
If the problem is running time, you should make sure that idsPercorridos is a TreeSet or HashSet, as these allow for efficient contains calls, as opposed to ArrayList or LinkedList, which don't.
If this doesn't help, you could try using the A* algorithm instead, which involves adding a heuristic function to each node, which is the distance to the target - this allows us to explore the nodes closer to the target first, often resulting in less steps to get there.
A good heuristic function might be the sum of Manhattan distances between each tile and its target location.
Note that this would involve quite a few changes to your current code.
According to Wikipedia there are 9!/2 = 181440 possible solvable combinations to this puzzle. If you check each node for each of these combinations (which you don't, but it makes the calculation easier), it makes about (9!/2) * 9 = 1,632,960 steps. Therefore, there I don't see an issue if it takes your algorithm 350,000 steps because a computer can do those steps really fast.
I am trying to sort a LinkedList in Java. I need to go through mylist from back to front. The elements in the list are objects from my class CustomElement. If they match a certain pattern I want to put them up front.
My problem is that if I detect that the element in my list with index 5 for example matches my pattern and I move it to index 0, the previous element with index 4 has index 5 now, right? That is why I want the for loop to check the element with index 5 again: i++. But that's causing an infinite loop, whreas the method's working fine without i++, but not the way that I want it, because it's skipping the element with index 4 (now 5).
Is it gernerally possible to raise the variable i inside the for loop? And if yes, what am I doing wrong.
for (int i = mylist.size() - 1; i >= 0; i--) {
if (mylist.get(i) matches a certain pattern) {
CustomElement helper = mylist.get(i);
mylist.remove(i);
mylist.add(0, helper);
i++;
}
}
Yes, it is possible to modify i inside your for loop, if it weren't possible, you wouldn't be getting this infinite loop.
What must be happening, is that if (mylist.get(i) matches a certain pattern) continues to be true after a certain point, and you never get to a point where i >= 0 is not true.
So, if myList.get(0) matches your pattern, you'll just put it back at index 0, and keep checking it forever.
It is, but in your case using get(i) for a linked list will give quadratic performance.
If you don't mind your "matching" items being reversed in order then you'd be better creating a new list:
final LinkedList<CustomElement> newList = new LinkedList<> ();
for (final CustomElement e: myList)
{
if (e matches your pattern) { newList.addFirst (e); }
else { newList.addLast (e); }
}
myList = newList;
Then all problems with index variables disappear...
(You could also achieve linear performance whilst modifying the existing list, but it's a little more complicated.)
This is from an old homework problem, that I already turned in, but I wasn't able to figure it out. I'm trying to remove an element from my LinkedList at a specific index using my user-defined class. Below is the pseudo code I'm working off of, but it doesn't have the same parameters as mine so I tried modifying it, but had an issue. I'm a programming noob (roughly 6 months of experience), just FYI. I understand ArrayLists just fine, but LinkedLists have been giving me trouble.
/*
* Remove the nth element in the list. The first element is element 1.
* Return the removed element to the caller.
function remove(List list, Node node)
if node.prev == null
list.firstNode := node.next
else
node.prev.next := node.next
if node.next == null
list.lastNode := node.prev
else
node.next.prev := node.prev
destroy node
*/
My method asks the user to enter an index position to delete. Because an int and LinkEntry are different types, naturally I'm having issues. I don't know how to incorporate the int that is passed through the parameter.
public void remove(int n)
{
LinkEntry<E> remove_this = new LinkEntry<E>();
remove_this.element = n;
for (remove_this = head; remove_this != null; remove_this = remove_this.next)
{
//removes the head if list is only 1 item long
if (head.next == null)
head = remove_this.next;
else
//sets previous element to the next element
remove_this.previous.next = remove_this.next;
//if nothing comes after remove_this, then remove the tail element
if (remove_this.next == null)
tail = remove_this.previous;
else
//sets next previous element to current previous element
remove_this.next.previous = remove_this.previous;
}
}
If you know of anywhere that gives another example that is more similar to what I'm trying to solve I would really appreciate it. I've looked through my text and online, but no luck.
You should set a counter to zero, browse your linked list from its first element (apparently named "head"), and increment the counter until its equal to n (or you reached the end of the list).
When counter equals to n, you must connect previous entry to next, and next to previous (so it deconnects the Nth). You also have to take care of special cases, when n=1 (you're supposed to delete "head" entry, that is to say set head to head.next), when next is null (n = list length), and when n negative or greater than list length.
When I learned this in galaxy far, far away ... it helped me to paint it on paper. Something like this:
You have
A B C
next *------>*------>*---->NULL
prev NULL<---*<------*-------*
and you want
A C
next *------>*---->NULL
prev NULL<---*<------*
So if you find B, you know what to do. But how to find B? B is the second element in our example above, so we'll be given a "1" in zero-based lists or a "2" in one-based lists.
A typical scenario would be to hold a reference to the first element of the list. This is often referred to as the "head". Now you would start with that head and follow its next-pointer. What do you get? The second element in the list. In our example that would already be our "B". Notice, that we followed next 1 time ... now assume we were to delete C. We got index 2 ( or one-based: 3) , we startet with head, followed next 1 time and got B. 1<2 so follow next again. Notice that we have to follow B's next instead of "head"'s So if using a loop, we'll have to use some sort of local var. Now we have the 2nd Element, which is C and remove it. Notice that C's "next" is null. So we are done in that direction.