Traversing a generic Trie in Java - java

I have a fully built generic Trie in java. I am trying to traverse through the Trie to obtain all the complete combinations for each path. For example, if the Trie contained chars then it would return all the word combinations. For my purposes, I am trying to put all the nodes for each combination into an array and return them. I am stumped however. I only came up with the traversal that goes through each child (+ subchildren) before going back to the parent/starting node (much like a BST traversal). I am using an ArrayList to hold the children for each node. Sorry if it is a bit confusing. A code sample or pseudo code will be much appreciated. Thanks.
EDIT
By combinations, I mean the following. If I had a Trie<char> that looked like the following:
"null"
/ | \
a i t
/ /|\ \
t f m n o
The combinations that I would want returned would be:
[a, t]
[i, f]
[i, m]
[i, n]
[t, o]
and all these arrays/lists could be in one single ArrayList which is returned at the end.

Do a recursive method to (at least) get all the chars in the tree. Just make sure you initialize the chars as an empty List
Stack startRead(Tree tree) {
// validation check
if (tree == null || !tree.hasChild()) return null;
// create Stack to store the lists
Stack listStack = new Stack();
// for every child
List children = tree.getChildren();
for (Tree child : children) {
// create a list
List childList = new ArrayList();
// store (push) it into stack
listStack.push(childList);
// call the recursive
readIt(child, listStack);
}
return listStack;
}
void readIt(Tree tree, Stack listStack) {
// pick the top list from stack
List current = (List) listStack.pop();
// this is the base; if tree has no child don't call this method again.
if (!tree.hasChild()) {
// if it's leaf add the value to current list
current.add(tree.getValue());
// push it back to stack
listStack.push(current);
} else {
// for every child
List children = tree.getChildren();
for (Tree child : children) {
// IMPORTANT! clone the list (if this fails, clone it yourself)
// clone is called when the tree is branching
List childList = current.clone();
// insert this tree value to list
childList.add(tree.getValue());
// push it back
listStack.push(childList);
// call again
readIt(child, listStack);
}
}
}
with this you will have a return value of a Stack consisting Lists of value for each combination.
Hope this helps. :)

Related

how to recurse over singly linked list with a function that takes no parameters

I'm trying to recursively loop over a singly linked-list but I have to use a function that takes no parameters and I'm a little confused how to do that. My thought process was that I would just keep passing in the modified list to the function but that's not what the problem asks for. This is the question:
Suppose that you have a singly linked list of ints without header, with the following class definition:
class IntList {
int value;
IntList next;
}
Write a recursive, owned method l.sumOfList() which:
destructively replaces the value at each node in the list with the sum of the values of the list starting at that point.
should return the sum of the values in the original list. For instance, if l is initially the list [3,2,1], and you call l.sumOfList() then l becomes the list [6=(3+2+1), 3(=2+1), 1].
I'm just not sure how to write a recursive function with no
parameters? Or how to work with a linked list without a header.
You can keep a class variable and use it in your recursive function. Something like;
class TraverseInt {
IntList node = start; // start of the linked list
public void traverse() {
if(node == null)
return;
System.out.println(node.value);
node = node.next;
traverse();
}
}

Remove node from linked list recursively

Given the head of a linked list and the int to search for as parameters, I need a method that will remove the first occurrence of this number in the list, and return the modified list. however i cannot modify the original list. I know how to remove the node from the list, but im not sure how i would keep the original list intact since this has to be done recursively. below is the method
** initially M is the original list. I dont know that it will still be the same list after calling the method again...?
MyList removeNumber(MyList m, int removee){
The idea is that the resulting structure will be a "Y": a two-headed list (actually a simple graph).
One branch of the Y is the original list. The other is your new list with removed node. The vertical stalk of the Y is what's after the element you remove. It's common to both lists. Here's some ascii art with the Y turned on its side showing a list of 1 to 5 with 3 removed.
new -> 1 -> 2 ------\
v
original -> 1 -> 2 -> 3 -> 4 -> 5 -> null
Thinking recursively is all about defining a problem in terms of a smaller version of itself plus a fixed bit of work. And you need a base case (or maybe several).
A linked list is itself a recursive structure:
A list is either empty or it's an element linked by its "next" reference to a list.
Note this defines a list using a smaller list. The base case is the empty list. The fixed bit is the element.
Read this definition a few times, then see how it translates the code:
class MyList {
int value; // the element at the head of this list
MyList next; // the rest of the list
MyList(int value, MyList next) {
this.value = value;
this.next = next;
}
}
The base case "empty list" is just a null reference. The element removal problem expressed recursively using the same pattern becomes:
A copy of a list with an element removed is either a) the rest of the list following the head in the case that the element to be removed is the head or b) a copy of the current node followed by a copy the rest of the list with the desired element removed.
Here I'm defining a "copy of a list with one element removed" using a smaller version of the same thing. Case a) is the base case. The fixed bit is copying the head when it's not the removee.
Of course there's another base case: if the list is empty, the removee can't be found. That's an error.
Putting this in code:
MyList removeNumber(MyList m, int removee) {
if (m == null) throw new RuntimeException("removee not found");
if (m.value == removee) return m.next;
return new MyList(m.value, removeNumber(m.next, removee));
}
Putting the function to use would look something like this:
MyList originalList = ... // list of 1 to 5.
MyList newListWith3removed = removeNumber(originalList, 3);
System.out.println("Original list:");
for (MyList p : originalList) System.out.println(p.value);
System.out.println("With 3 removed:");
for (MyList p : newListWith3removed) System.out.println(p.value);
The output will look as expected: 1 to 5 in the first list and 1,2,4,5 in the second. I.e. the first list is unchanged.
//This function will always return a new list with 'remove' removed
MyList removeNumber(MyList m, int remove){
//if m is empty List, return an empty list
//if head is not the int to remove, return a New list from
// head concat removeNumber(m.next,remove)
//else return removeNumber(m.next,remove)
}
I think it lacks information. I'm assuming however a very traditional implementation for linked list, for instance:
class MyList {
MyList prev;
MyList next;
int data;
static MyList removeNumber(MyList m,int removee) {
if(m == null) return null; // already empty
if(m.data == removee) { // m already is the node to throw away
if(m.prev != null)// relink
m.prev.next = m.next;
if(m.next != null)// relink
m.next.prev = m.prev;
return m.prev;
}
// if this node isn't the one yet, keep looking for
return removeNumber(m.next,removee);
}
}
There are plenty different ways to do that, but you have to provide more info in order to allow us to point you the correct literature.

Implementing Linked List in JAVA (Reverse without using iterator)

I am trying to implement the linkedList class, adding a method reverse(int n) to reverse the linked list. For example, I have a linked list { A -> B -> C -> D -> E). When I call reverse(4), the linked list will become D-->C-->B-->A-->E.
I am trying to avoid using iterator, constructing new node and copying the data value. Does anyone have idea how to do it? I know there was a post about reversing linked list but that one is reversing the entire linked list.
Thank you so much for the help!
Since you don't provide your implementation of the LinkedList, i can only provide the general idea:
The complete list can be reversed by simply swaping the pointers to the previous node and the next node and updating the fields for the last and first node.
void reverse()
node tmp = first
first = last
last = tmp
while(tmp.next != null)
node swap = tmp.next
tmp.next = tmp.previous
tmp.previous = swap
tmp = swap
I'll leave it to you to add the bounds

TreeSet not Re-Ordering Itself after Values in it are Changed

I have a TreeSet in JAVA which orders a custom datatype called 'Node'. However, the TreeSet does not order itself properly.
A link to my complete implementation is at the bottom. Let me explain my probelm in detail first
Here have a custome datatype 'Node'. It has 2 parameters as such. A character and a number associated to it. Say something like:
pair<char,int> node;
in C++.
Here is the code:
class Node
{
char c;int s;
Node(char x,int y)
{
c=x;s=y;
}
}
I implemented a Comparator for this TreeSet which order the elements in descending order of 's'. So for example we have 2 nodes one is (a,2) and the other is (b,5), the they will be ordered as (b,5);(a,2). However, if their size is the same, the lexicographically smaller character will come first.
TreeSet<Node> ts=new TreeSet<Node>(new Comparator<Node>()
{
#Override
public int compare(Node o1, Node o2)
{
if(o2.s!=o1.s)
{
return o2.s-o1.s;
}
return (o1.c-o2.c);
}
});
Now i input the values as Following:
ts.add(new Node('a',3));
ts.add(new Node('b',2));
ts.add(new Node('c',1));
Now here is the operation I want to perform:
Pick the element at the head of the TreeSet. Call it a node. Print it
Check for 's' or the number associated with this node. Reduce it by 1
If s becomes 0, remove the node all together from the TreeSet
Keep performing this expression till the TreeSet is empty
Here is my implementaion:
while(ts.size()!=0)
{
Node node=ts.first();
System.out.println(node.c+" "+node.s);//Printing the character and the number associated with it
if(node.s==1)
{
ts.pollFirst();//removing redundant node as reducing it by 1 will become 0
}
else
{
ts.first().s--;//Reducing it's size
}
}
Well here is my probelem:
Current Output: Expected Output:
a 3 a 3
a 2 a 2
a 1 //In this iteration, b has the largest number b 2
b 2 a 1
b 1 b 1
c 1 c 1
Why is the TreeSet not reordering itself and behaving more like a List? How do I rectify this?
I've gotten used to the idea of a 'Comparator' quite recently so please excuse me for a few goof ups in the implementation if any.
Here is the complete implementation: http://ideone.com/As35FO
The TreeSet won't reorder itself when you change the value of the elements. You have to take the elements out and re-add them if you want them to remain ordered:
Node first = ts.pollFirst();
first.s--;
ts.add(first);

Convert Java Code to Objective-C Code?

Can any one help me converting the following Java Code into Objective-C Code. I knew Objective-C but I am not able to translate this code into objective-C.
This is Java Code.
public MyList RecReverse() { //my attempt at the recursive method
if (head.getNext() == null) {
return this;
}
MyList remainder = new MyList();
remainder.head = head.getNext(); // New list has rest of this list (after head)
ListNode temp = new ListNode(head.getString()); // save the first thing in list
remainder = remainder.RecReverse(); //reverse the things in the new 2nd part list
remainder.end().setNext(temp); // put old head on the end
return remainder;
}
private ListNode end() {
ListNode curr = head;
while (curr.getNext() != null) {
curr = curr.getNext();
}
return curr;
}
Thanks
The code is a poor algorithm for reversing a linked list. You presumably have either converted the rest of the class, or have your own linked list class and are just trying to copy the reversal algorithm. You should really include these details and what you've tried when you ask questions on SO, without them people answering can often only guess and you've failed to show any effort - the latter is important.
While this code strongly suggests a linked list there is no clue in this fragment whether this is a single or double-linked list. The code fragment you supply indicates that you have a MyList class with manages a linked list made up of ListNode objects.
The basic operations on a linked list are typically:
Access/change the value stored in the current node - in your code this is the property head and it is an object reference of type ListNode; which itself appears to hold a string.
Access/change the reference to the remainder ("tail") of the list - in your code the getNext & setNext methods.
The method you show RecReverse is a way to recursively produce a new list which is the reverse of the current list. The algorithm does this by reversing the tail of the list and then appending the head onto the end - using the method end.
If the list is double-linked and/or keeps a reference to the end of the list then the algorithm is ok - the method end does not need to traverse the list in this case. Just write it in Objective-C and add it to your list class.
If the list is single-linked and does not keep a reference to the end of the list then the algorithm is poor and the method end does need to traverse the list. This makes it an O(n^2) algorithm - every step traverses the list.
A better algorithm in this case is to use an accumulating parameter. In pseudo-code this is:
Reverse(l)
if length(l) <= 1
then return l // empty list or list with one element reversed is itself
else return ReverseHelper(l, new empty list)
ReverseHelp(remainder, result)
if remainder is empty
then return result // no more elements left to process
else return ReverseHelp(tail of remainder, add head of remainder to front of result)
Implement that on Objective-C and add it to your linked list class.
HTH
You haven't really given context to what 'MyList' objects are.
But if you are simply attempting to reverse an array using any method possibly you can use the following single line:
NSArray* reversedArray = [[array reverseObjectEnumerator] allObjects];

Categories