Lisp Linked List Emulation Java - java

For my assignment we are to make an emulation of a LISP Linked List in Java. There are two types of List, an EmptyList and a NonEmptyList. The EmptyList is mostly trivial and only serves the purpose of ending the Linked List. The way it is supposed to work is that each List has a head and a tail. The head is an Object and the Tail is the next Linked List. I have a Linked List interface as follows:
public interface LispList {
EmptyList NIL = new EmptyList();
boolean empty();
Object head();
LispList tail();
LispList cons(Object inputHead);
}
And here is the NonEmptyList class:
public class NonEmptyList implements LispList{
Object head;
LispList tail;
public NonEmptyList(Object inputHead) {
this.head = inputHead;
this.tail = new NonEmptyList(head);
}
public boolean empty() {
return false;
}
public Object head() {
return head;
}
public LispList tail() {
return tail;
}
public String toString() {
return head() + " " + tail().toString();
}
public NonEmptyList cons(Object inputHead) {
NonEmptyList a = new NonEmptyList(inputHead);
return a;
}
public class NIL{
EmptyList NIL;
}
}
EmptyList:
public class EmptyList implements LispList {
public EmptyList() {
}
public boolean empty() {
return true;
}
public Object head() {
throw new UnsupportedOperationException("EmptyList");
}
public LispList tail() {
throw new UnsupportedOperationException("EmptyList");
}
public String toString() {
return "";
}
public class NIL{
EmptyList NIL;
}
public NonEmptyList cons(Object inputHead) {
NonEmptyList a = new NonEmptyList(inputHead);
return a;
}
}
And here is my tester:
public class LispListTest {
public static void main(String[] args) {
LispList list = LispList.NIL.cons("C").cons("B").cons("A");
System.out.println(list.tail());
System.out.println(list.toString());
}
}
The problem I am having is in the constructor of the NonEmptyList. The way I have it currently gives me a Stack Overflow Exception. I have tried a few different things and none of them work the way I need them to. I'm not sure how to make the constructor so the tail points to the next list.
This is my first attempt at a linked list so I might be making a pretty simple mistake.

Short anwser
First, EmptyList class needs to be singleton. Not sure how to achieve it Java, but you shouldn't open the constructor to everybody to use.
Then, the constructor for NonEmptyList should take two arguments:
The object for the head.
The tail, the instance of LispList. Better if you overload the constructor with this argument defaulting to EmptyList (singleton) instance.
Currently, in the constructor NonEmptyList you recursively call it when assigning the tail: in a way you are constructing an infinite list with repeated element: (a) this is not what you want and (b) without laziness this will cause stack overflow.
Lastly, cons is a constructor for a non-empty list, thus there is no need for a method called cons.
A guide into Lisp lists
Most Lisp dialects construct the list on the top of a pair. There is some criticism about the way Lisps do it: this introduces concepts of proper and improper lists and it's hard to define a generic comparison on lists. Yet, it's an easy and efficient way to do it.
A pair is constructed using CONS function (I will be using Common Lisp, CL, for demonstration):
(cons 12 45) => (12 . 45)
Notice the dot in the printed form of the pair. Parts of the pair can be extracted using functions CAR and CDR:
(car (cons 12 45)) => 12
(cdr (cons 12 45)) => 45
Pairs can be combined with other pairs:
(cons (cons (cons 1 2) 3) (cons 4 5))
=> (((1 . 2) . 3) 4 . 5)
CL provides combination functions of CAR and CDR to extract sub-pairs, e.g. CDDAR is a shortcut for (CDR (CDR (CAR OBJ))): it takes the first item of the pair (which must be a pair itself), then the second item of the result and the second item of that result.
Lisps also define a special object of an empty pair, or nothing (but in fact, this object is not a pair, it's like mathematical "empty set" which is not a set...). In CL there two synonyms for it: NIL or ().
A list is constructed using pairs ordered in certain way. A list is:
Either NIL, or empty
Or a (CONS OBJ TAIL), where OBJ is any object and TAIL is a list.
To distinguish operations on pairs and their combinations from operations on lists, Common Lisp provides synonymous functions:
FIRST extracts the first item of the list (aka head), synonym for CAR.
REST returns the tail of the list, synonym for (CAR (CDR LIST)) or (CADR LIST).
So, here are examples of lists:
NIL is an empty list
(CONS 1 NIL) (printed (1)) is the list of one element; FIRST will return 1 and REST will return an empty list NIL.
(CONS 1 (CONS 2 NIL)) (printed (1 2)) is the list of two elements; FIRST will return 1 and REST will return the tail list (2).
Generally, the list of numbers from 1 to N will be (CONS 1 (CONS 2 (CONS 3 ... (CONS N NIL) ..))).

Here is correct and tested answer:
LispList interface:
public interface LispList
{
LispList NIL = new EmptyList();
boolean isEmpty();
Object head();
LispList tail();
LispList cons(Object head);
}
EmptyList class
public class EmptyList implements LispList {
public String toString() {
return "";
}
#Override
public boolean isEmpty() {
return true;
}
#Override
public Object head() {
throw new UnsupportedOperationException();
}
#Override
public LispList tail() {
throw new UnsupportedOperationException();
}
#Override
public LispList cons(Object head) {
return new NonEmptyList(head, new EmptyList());
}
}
NonEmptyList class
public class NonEmptyList implements LispList {
private LispList tail;
private Object head;
public NonEmptyList(Object head, LispList tail) {
this.head = head;
this.tail = tail;
}
public String toString() {
return head() + " " + tail().toString();
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public Object head() {
return head;
}
#Override
public LispList tail() {
return tail;
}
#Override
public LispList cons(Object head) {
return new NonEmptyList(head, new NonEmptyList(head(), tail));
}
}
And test main class:
public class LispListTester
{
public static void main(String[] args)
{
LispList list1 = new EmptyList();
System.out.println("[" + list1 + "]");
System.out.println("Expected: []");
LispList list2 = new NonEmptyList("A", new EmptyList());
System.out.println(list2);
System.out.println("Expected: A");
LispList list3 = new NonEmptyList("A", new NonEmptyList("B",
new NonEmptyList("C", new EmptyList())));
System.out.println(list3);
System.out.println("Expected: A B C");
LispList list4 = LispList.NIL.cons("E").cons("D").cons("C").cons("B").cons("A");
System.out.println(list4);
System.out.println("Expected: A B C D E");
}
}

Related

How to sort a list when certain values must appear later than others, potentially ignoring sort order for such items that need 'delaying' [duplicate]

This question already has answers here:
Sample Directed Graph and Topological Sort Code [closed]
(7 answers)
Closed 4 years ago.
Problem
I have the requirement to sort a list by a certain property of each object in that list. This is a standard action supported in most languages.
However, there is additional requirement that certain items may depend on others, and as such, must not appear in the sorted list until items they depend on have appeared first, even if this requires going against the normal sort order. Any such item that is 'blocked', should appear in the list the moment the items 'blocking' it have been added to the output list.
An Example
If I have items:
[{'a',6},{'b',1},{'c',5},{'d',15},{'e',12},{'f',20},{'g',14},{'h',7}]
Sorting these normally by the numeric value will get:
[{'b',1},{'c',5},{'a',6},{'h',7},{'e',12},{'g',14},{'d',15},{'f',20}]
However, if the following constraints are enforced:
a depends on e
g depends on d
c depends on b
Then this result is invalid. Instead, the result should be:
[{'b',1},{'c',5},{'h',7},{'e',12},{'a',6},{'d',15},{'g',14},{'f',20}]
Where b, c, d, e, f and h have been sorted in correct order b, c, h, e, d and f; both a and g got delayed until e and d respectively had been output; and c did not need delaying, as the value it depended on, b, had already been output.
What I have already tried
Initially I investigated if this was possible using basic Java comparators, where the comparator implementation was something like:
private Map<MyObject,Set<MyObject>> dependencies; // parent to set of children
public int compare(MyObj x, MyObj y) {
if (dependencies.get(x).contains(y)) {
return 1;
} else if (dependencies.get(y).contains(x)) {
return -1;
} else if (x.getValue() < y.getValue()) {
return -1;
} else if (x.getValue() > y.getValue()) {
return 1;
} else {
return 0;
}
}
However this breaks the requirement of Java comparators of being transitive. Taken from the java documentation:
((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.
However, in the above example
a(6) < h(7) : true
h(7) < e(12) : true
a(6) < e(12) : false
Instead, I have come up with the below code, which while works, seems massively over-sized and over-complex for what seems like a simple problem. (Note: This is a slightly cut down version of the class. It can also be viewed and run at https://ideone.com/XrhSeA)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public final class ListManager<ValueType extends Comparable<ValueType>> {
private static final class ParentChildrenWrapper<ValueType> {
private final ValueType parent;
private final Set<ValueType> childrenByReference;
public ParentChildrenWrapper(ValueType parent, Set<ValueType> childrenByReference) {
this.parent = parent;
this.childrenByReference = childrenByReference;
}
public ValueType getParent() {
return this.parent;
}
public Set<ValueType> getChildrenByReference() {
return this.childrenByReference;
}
}
private static final class QueuedItem<ValueType> implements Comparable<QueuedItem<ValueType>> {
private final ValueType item;
private final int index;
public QueuedItem(ValueType item, int index) {
this.item = item;
this.index = index;
}
public ValueType getItem() {
return this.item;
}
public int getIndex() {
return this.index;
}
#Override
public int compareTo(QueuedItem<ValueType> other) {
if (this.index < other.index) {
return -1;
} else if (this.index > other.index) {
return 1;
} else {
return 0;
}
}
}
private final Set<ValueType> unsortedItems;
private final Map<ValueType, Set<ValueType>> dependentsOfParents;
public ListManager() {
this.unsortedItems = new HashSet<>();
this.dependentsOfParents = new HashMap<>();
}
public void addItem(ValueType value) {
this.unsortedItems.add(value);
}
public final void registerDependency(ValueType parent, ValueType child) {
if (!this.unsortedItems.contains(parent)) {
throw new IllegalArgumentException("Unrecognized parent");
} else if (!this.unsortedItems.contains(child)) {
throw new IllegalArgumentException("Unrecognized child");
} else if (Objects.equals(parent,child)) {
throw new IllegalArgumentException("Parent and child are the same");
} else {
this.dependentsOfParents.computeIfAbsent(parent, __ -> new HashSet<>()).add(child);
}
}
public List<ValueType> createSortedList() {
// Create a copy of dependentsOfParents where the sets of children can be modified without impacting the original.
// These sets will representing the set of children for each parent that are yet to be dealt with, and such sets will shrink as more items are processed.
Map<ValueType, Set<ValueType>> blockingDependentsOfParents = new HashMap<>(this.dependentsOfParents.size());
for (Map.Entry<ValueType, Set<ValueType>> parentEntry : this.dependentsOfParents.entrySet()) {
Set<ValueType> childrenOfParent = parentEntry.getValue();
if (childrenOfParent != null && !childrenOfParent.isEmpty()) {
blockingDependentsOfParents.put(parentEntry.getKey(), new HashSet<>(childrenOfParent));
}
}
// Compute a list of which children impact which parents, alongside the set of children belonging to each parent.
// This will allow a child to remove itself from all of it's parents' lists of blocking children.
Map<ValueType,List<ParentChildrenWrapper<ValueType>>> childImpacts = new HashMap<>();
for (Map.Entry<ValueType, Set<ValueType>> entry : blockingDependentsOfParents.entrySet()) {
ValueType parent = entry.getKey();
Set<ValueType> childrenForParent = entry.getValue();
ParentChildrenWrapper<ValueType> childrenForParentWrapped = new ParentChildrenWrapper<>(parent,childrenForParent);
for (ValueType child : childrenForParent) {
childImpacts.computeIfAbsent(child, __ -> new LinkedList<>()).add(childrenForParentWrapped);
}
}
// If there are no relationships, the remaining code can be massively optimised.
boolean hasNoRelationships = blockingDependentsOfParents.isEmpty();
// Create a pre-sorted stream of items.
Stream<ValueType> rankedItemStream = this.unsortedItems.stream().sorted();
List<ValueType> outputList;
if (hasNoRelationships) {
// There are no relationships, and as such, the stream is already in a perfectly fine order.
outputList = rankedItemStream.collect(Collectors.toList());
} else {
Iterator<ValueType> rankedIterator = rankedItemStream.iterator();
int queueIndex = 0;
outputList = new ArrayList<>(this.unsortedItems.size());
// A collection of items that have been visited but are blocked by children, stored in map form for easy deletion.
Map<ValueType,QueuedItem<ValueType>> lockedItems = new HashMap<>();
// A list of items that have been freed from their blocking children, but have yet to be processed, ordered by order originally encountered.
PriorityQueue<QueuedItem<ValueType>> freedItems = new PriorityQueue<>();
while (true) {
// Grab the earliest-seen item which was once locked but has now been freed. Otherwise, grab the next unseen item.
ValueType item;
boolean mustBeUnblocked;
QueuedItem<ValueType> queuedItem = freedItems.poll();
if (queuedItem == null) {
if (rankedIterator.hasNext()) {
item = rankedIterator.next();
mustBeUnblocked = false;
} else {
break;
}
} else {
item = queuedItem.getItem();
mustBeUnblocked = true;
}
// See if this item has any children that are blocking it from being added to the output list.
Set<ValueType> childrenWaitingUpon = blockingDependentsOfParents.get(item);
if (childrenWaitingUpon == null || childrenWaitingUpon.isEmpty()) {
// There are no children blocking this item, so start removing it from all blocking lists.
// Get a list of all parents that is item was blocking, if there are any.
List<ParentChildrenWrapper<ValueType>> childImpact = childImpacts.get(item);
if (childImpact != null) {
// Iterate over all those parents
ListIterator<ParentChildrenWrapper<ValueType>> childImpactIterator = childImpact.listIterator();
while (childImpactIterator.hasNext()) {
// Remove this item from that parent's blocking children.
ParentChildrenWrapper<ValueType> wrappedParentImpactedByChild = childImpactIterator.next();
Set<ValueType> childrenOfParentImpactedByChild = wrappedParentImpactedByChild.getChildrenByReference();
childrenOfParentImpactedByChild.remove(item);
// Does this parent no longer have any children blocking it?
if (childrenOfParentImpactedByChild.isEmpty()) {
// Remove it from the children impacts map, to prevent unnecessary processing of a now empty set in future iterations.
childImpactIterator.remove();
// If this parent was locked, mark it as now freed.
QueuedItem<ValueType> freedQueuedItem = lockedItems.remove(wrappedParentImpactedByChild.getParent());
if (freedQueuedItem != null) {
freedItems.add(freedQueuedItem);
}
}
}
// If there are no longer any parents at all being blocked by this child, remove it from the map.
if (childImpact.isEmpty()) {
childImpacts.remove(item);
}
}
outputList.add(item);
} else if (mustBeUnblocked) {
throw new IllegalStateException("Freed item is still blocked. This should not happen.");
} else {
// Mark the item as locked.
lockedItems.put(item,new QueuedItem<>(item,queueIndex++));
}
}
// Check that all items were processed successfully. Given there is only one path that will add an item to to the output list without an exception, we can just compare sizes.
if (outputList.size() != this.unsortedItems.size()) {
throw new IllegalStateException("Could not complete ordering. Are there recursive chains of items?");
}
}
return outputList;
}
}
My question
Is there an already existing algorithm, or an algorithm significantly shorter than the above, that will allow this to be done?
While the language I am developing in is Java, and the code above is in Java, language-independent answers that I could implement in Java are also fine.
This is called topological sorting. You can model "blocking" as edges of a directed graph. This should work if there are no circular "blockings".
I've done this in <100 lines of c# code (with comments). This implementation seems a little complicated.
Here is the outline of the algorithm
Create a priority queue that is keyed by value that you want to sort by
Insert all the items that do not have any "blocking" connections incoming
While there are elements in the queue:
Take an element of the queue. Put it in your resulting list.
If there are any elements that were being directly blocked by this element and were not visited previously, put them into the queue (an element can have more than one blocking element, so you check for that)
A list of unprocessed elements should be empty at the end, or you had a cycle in your dependencies.
This is essentialy Topological sort with built in priority for nodes. Keep in mind that the result can be quite suprising depending on the number of connections in your graph (ex. it's possible to actually get elements that are in reverse order).
As Pratik Deoghare stated in their answer, you can use topological sorting. You can view your "dependencies" as arcs of a Directed Acyclic Graph (DAG). The restriction that the dependencies on the objects are acyclic is important as topological sorting is only possible "if and only if the graph has no directed cycles." The dependencies also of course don't make sense otherwise (i.e. a depends on b and b depends on a doesn't make sense because this is a cyclic dependency).
Once you do topological sorting, the graph can be interpreted as having "layers". To finish the solution, you need to sort within these layers. If there are no dependencies in the objects, this leads to there being just one layer where all the nodes in the DAG are on the same layer and then they are sorted based on their value.
The overall running time is still O(n log n) because topological sorting is O(n) and sorting within the layers is O(n log n). See topological sorting wiki for full running time analysis.
Since you said any language that could be converted to Java, I've done a combination of [what I think is] your algorithm and ghord's in C.
A lot of the code is boilerplate to handle arrays, searches, and array/list insertions that I believe can be reduced by using standard Java primitives. Thus, the amount of actual algorithm code is fairly small.
The algorithm I came up with is:
Given: A raw list of all elements and a dependency list
Copy elements that depend on another element to a "hold" list. Otherwise, copy them to a "sort" list.
Note: an alternative is to only use the sort list and just remove the nodes that depend on another to the hold list.
Sort the "sort" list.
For all elements in the dependency list, find the corresponding nodes in the sort list and the hold list. Insert the hold element into the sort list after the corresponding sort element.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
// sort node definition
typedef struct {
int key;
int val;
} Node;
// dependency definition
typedef struct {
int keybef; // key of node that keyaft depends on
int keyaft; // key of node to insert
} Dep;
// raw list of all nodes
Node rawlist[] = {
{'a',6}, // depends on e
{'b',1},
{'c',5}, // depends on b
{'d',15},
{'e',12},
{'f',20},
{'g',14}, // depends on d
{'h',7}
};
// dependency list
Dep deplist[] = {
{'e','a'},
{'b','c'},
{'d','g'},
{0,0}
};
#define MAXLIST (sizeof(rawlist) / sizeof(rawlist[0]))
// hold list -- all nodes that depend on another
int holdcnt;
Node holdlist[MAXLIST];
// sort list -- all nodes that do _not_ depend on another
int sortcnt;
Node sortlist[MAXLIST];
// prtlist -- print all nodes in a list
void
prtlist(Node *node,int nodecnt,const char *tag)
{
printf("%s:\n",tag);
for (; nodecnt > 0; --nodecnt, ++node)
printf(" %c:%d\n",node->key,node->val);
}
// placenode -- put node into hold list or sort list
void
placenode(Node *node)
{
Dep *dep;
int holdflg;
holdflg = 0;
// decide if node depends on another
for (dep = deplist; dep->keybef != 0; ++dep) {
holdflg = (node->key == dep->keyaft);
if (holdflg)
break;
}
if (holdflg)
holdlist[holdcnt++] = *node;
else
sortlist[sortcnt++] = *node;
}
// sortcmp -- qsort compare function
int
sortcmp(const void *vlhs,const void *vrhs)
{
const Node *lhs = vlhs;
const Node *rhs = vrhs;
int cmpflg;
cmpflg = lhs->val - rhs->val;
return cmpflg;
}
// findnode -- find node in list that matches the given key
Node *
findnode(Node *node,int nodecnt,int key)
{
for (; nodecnt > 0; --nodecnt, ++node) {
if (node->key == key)
break;
}
return node;
}
// insert -- insert hold node into sorted list at correct spot
void
insert(Node *sort,Node *hold)
{
Node prev;
Node next;
int sortidx;
prev = *sort;
*sort = *hold;
++sortcnt;
for (; sort < &sortlist[sortcnt]; ++sort) {
next = *sort;
*sort = prev;
prev = next;
}
}
int
main(void)
{
Node *node;
Node *sort;
Node *hold;
Dep *dep;
prtlist(rawlist,MAXLIST,"RAW");
printf("DEP:\n");
for (dep = deplist; dep->keybef != 0; ++dep)
printf(" %c depends on %c\n",dep->keyaft,dep->keybef);
// place nodes into hold list or sort list
for (node = rawlist; node < &rawlist[MAXLIST]; ++node)
placenode(node);
prtlist(sortlist,sortcnt,"SORT");
prtlist(holdlist,holdcnt,"HOLD");
// sort the "sort" list
qsort(sortlist,sortcnt,sizeof(Node),sortcmp);
prtlist(sortlist,sortcnt,"SORT");
// add nodes from hold list to sort list
for (dep = deplist; dep->keybef != 0; ++dep) {
printf("inserting %c after %c\n",dep->keyaft,dep->keybef);
sort = findnode(sortlist,sortcnt,dep->keybef);
hold = findnode(holdlist,holdcnt,dep->keyaft);
insert(sort,hold);
prtlist(sortlist,sortcnt,"POST");
}
return 0;
}
Here's the program output:
RAW:
a:6
b:1
c:5
d:15
e:12
f:20
g:14
h:7
DEP:
a depends on e
c depends on b
g depends on d
SORT:
b:1
d:15
e:12
f:20
h:7
HOLD:
a:6
c:5
g:14
SORT:
b:1
h:7
e:12
d:15
f:20
inserting a after e
POST:
b:1
h:7
e:12
a:6
d:15
f:20
inserting c after b
POST:
b:1
c:5
h:7
e:12
a:6
d:15
f:20
inserting g after d
POST:
b:1
c:5
h:7
e:12
a:6
d:15
g:14
f:20
I think you are generally on the right track, and the core concept behind your solution is similar to the one I will post below. The general algorithm is as follows:
Create a map that associates each item to the items that depend upon it.
Insert elements with no dependencies into a heap.
Remove the top element from the heap.
Subtract 1 from dependency count of each dependent of the element.
Add any elements with a dependency count of zero to the heap.
Repeat from step 3 until the heap is empty.
For simplicity I have replaced your ValueType with a String, but the same concepts apply.
The BlockedItem class:
import java.util.ArrayList;
import java.util.List;
public class BlockedItem implements Comparable<BlockedItem> {
private String value;
private int index;
private List<BlockedItem> dependentUpon;
private int dependencies;
public BlockedItem(String value, int index){
this.value = value;
this.index = index;
this.dependentUpon = new ArrayList<>();
this.dependencies = 0;
}
public String getValue() {
return value;
}
public List<BlockedItem> getDependentUpon() {
return dependentUpon;
}
public void addDependency(BlockedItem dependentUpon) {
this.dependentUpon.add(dependentUpon);
this.dependencies++;
}
#Override
public int compareTo(BlockedItem other){
return this.index - other.index;
}
public int countDependencies() {
return dependencies;
}
public int subtractDependent(){
return --this.dependencies;
}
#Override
public String toString(){
return "{'" + this.value + "', " + this.index + "}";
}
}
The BlockedItemHeapSort class:
import java.util.*;
public class BlockedItemHeapSort {
//maps all blockedItems to the blockItems which depend on them
private static Map<String, Set<BlockedItem>> generateBlockedMap(List<BlockedItem> unsortedList){
Map<String, Set<BlockedItem>> blockedMap = new HashMap<>();
//initialize a set for each element
unsortedList.stream().forEach(item -> {
Set<BlockedItem> dependents = new HashSet<>();
blockedMap.put(item.getValue(), dependents);
});
//place each element in the sets corresponding to its dependencies
unsortedList.stream().forEach(item -> {
if(item.countDependencies() > 0){
item.getDependentUpon().stream().forEach(dependency -> blockedMap.get(dependency.getValue()).add(item));
}
});
return blockedMap;
}
public static List<BlockedItem> sortBlockedItems(List<BlockedItem> unsortedList){
List<BlockedItem> sorted = new ArrayList<>();
Map<String, Set<BlockedItem>> blockedMap = generateBlockedMap(unsortedList);
PriorityQueue<BlockedItem> itemHeap = new PriorityQueue<>();
//put elements with no dependencies in the heap
unsortedList.stream().forEach(item -> {
if(item.countDependencies() == 0) itemHeap.add(item);
});
while(itemHeap.size() > 0){
//get the top element
BlockedItem item = itemHeap.poll();
sorted.add(item);
//for each element that depends upon item, decrease its dependency count
//if it has a zero dependency count after subtraction, add it to the heap
if(!blockedMap.get(item.getValue()).isEmpty()){
blockedMap.get(item.getValue()).stream().forEach(dependent -> {
if(dependent.subtractDependent() == 0) itemHeap.add(dependent);
});
}
}
return sorted;
}
}
You can modify this to more closely fit your use-case.
Java Code for topological sort:
static List<ValueType> topoSort(List<ValueType> vertices) {
List<ValueType> result = new ArrayList<>();
List<ValueType> todo = new LinkedList<>();
Collections.sort(vertices);
for (ValueType v : vertices){
todo.add(v);
}
outer:
while (!todo.isEmpty()) {
for (ValueType r : todo) {
if (!hasDependency(r, todo)) {
todo.remove(r);
result.add(r);
// no need to worry about concurrent modification
continue outer;
}
}
}
return result;
}
static boolean hasDependency(ValueType r, List<ValueType> todo) {
for (ValueType c : todo) {
if (r.getDependencies().contains(c))
return true;
}
return false;
}
ValueType is described like below:
class ValueType implements Comparable<ValueType> {
private Integer index;
private String value;
private List<ValueType> dependencies;
public ValueType(int index, String value, ValueType...dependencies){
this.index = index;
this.value = value;
this.dependencies = dependencies==null?null:Arrays.asList(dependencies);
}
public List<ValueType> getDependencies() {
return dependencies;
}
public void setDependencies(List<ValueType> dependencies) {
this.dependencies = dependencies;
}
#Override
public int compareTo(#NotNull ValueType o) {
return this.index.compareTo(o.index);
}
#Override
public String toString() {
return value +"(" + index +")";
}
}
And tested with these values:
public static void main(String[] args) {
//[{'a',6},{'b',1},{'c',5},{'d',15},{'e',12},{'f',20},{'g',14},{'h',7}]
//a depends on e
//g depends on d
//c depends on b
ValueType b = new ValueType(1,"b");
ValueType c = new ValueType(5,"c", b);
ValueType d = new ValueType(15,"d");
ValueType e = new ValueType(12,"e");
ValueType a = new ValueType(6,"a", e);
ValueType f = new ValueType(20,"f");
ValueType g = new ValueType(14,"g", d);
ValueType h = new ValueType(7,"h");
List<ValueType> valueTypes = Arrays.asList(a,b,c,d,e,f,g,h);
List<ValueType> r = topoSort(valueTypes);
for(ValueType v: r){
System.out.println(v);
}
}

How LinkedList object output the content using Syso? [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 3 years ago.
I have written a small piece of code to implement a linked list data structure. I have an internal class "Node" that has two fields Node and value. Constructor of Linked list accept int value parameter and assign that value to the Node object and add the Node object to the LinkedList object.
My question is which code of java.util.LinkedList makes the list object to be printed as a list of number but not the address of its object?
As When i print "list1", the output is [3,4].
When I print "list", the output is hashcode of the object address.
I didn't find the toString() in java.util.LinkedList class.
How can I make my code to print the content of LinkedList?
Below is the code:
class LinkedList {
Node first;
Node getNode(){
return new Node();
}
class Node{
Node next;
int value;
}
void add(int value){
Node n=this.getNode();
n.value=value;
n.next=null;
if (first==null){
first=n;
} else{
first.next=n;
}
}
}
public class LinkedListTest{
public static void main(String[] args) {
LinkedList list=new LinkedList();
java.util.LinkedList<Integer> list1=new java.util.LinkedList<>();
list1.add(3);
list1.add(4);
list.add(1);
list.add(2);
System.out.println(list);
System.out.println(list1);
}
}
Your class LinkedList (I suggest you rename it since it might be confused with java.util.LinkedList) needs to override the method Object::toString, which is called within printing out to a console.
I didn't find the toString() in java.util.LinkedList class.
A bit detective job - you have to click through the source codes of LinkedList<E> which extends AbstractSequentialList<E> which extends AbstractList<E> which finally extends AbstractCollection<E> (source code) class where is overridden Object::toString method responsible for the String-alike representation of all the element. There you can get inspired.
How can I make my code to print the content of LinkedList?
This way:
#Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
if (first != null) {
Node temp = first;
String sep = "";
while (temp != null) {
sb.append(sep).append(temp.value);
temp = temp.next;
sep = ", ";
}
}
return sb.append(']').toString();
}
You have to create your own toString method for example
class LinkedList {
//...
#Override
public String toString() {
StringBuilder text = new StringBuilder("[");
String del = "";
if (first != null) {
do {
text.append(del).append(first.value);
first = first.next;
del = ", ";
} while (first != null);
}
text.append(']');
return text.toString();
}
}
If you run your code again, the Outputs
[1, 2]

Java - creating Object without change the Original one

would it be possible to create new Object with the attributes from the Original Object without changing it ?
For example :
public void exampleTests() {
Tree t = Trees.makeTree(new int[]{2, 3, 4, 4, 1});//creating tree
assertTrue(t.contains(4)); //check if 4 is a node
assertFalse(t.contains(6));//check if 6 is a node
assertEquals(4, t.size()); //return size-nodes number (only different digits)
Tree t2 = t.add(6).add(7).add(6); // obj 2 take obj 1 and add 6 and 7 to it
assertFalse(t.contains(6)); // the first object should have no 6
assertTrue(t2.contains(6)); // the second object should have 6
Trees class :
public class Trees {
public static Tree makeTree(int[] elements) {
Tree tree = new Nodes();
for (int i : elements) {
tree.add(i);
}
return tree;
}
}
Tree interface
public interface Tree {
public Tree add(int i);
public boolean contains(int i);
public int size();
public String elementsAsString();
Node Class :
public class Node {
int i;
Node left;
Node right;
public Node(int data) {
this.i = data;
left = null;
right = null;
}
}
Nodes class :
public class Nodes implements Tree {
private Node root;
public Nodes() {
this.root = null;
}
#Override
public Nodes add(int i) {
root = insertNode(root, new Node(i));
return new Nodes();
}
private Node insertNode(Node currentParent, Node newNode) {
if (currentParent == null) {
return newNode;
} else if (newNode.i > currentParent.i) {
currentParent.right = insertNode(currentParent.right, newNode);
} else if (newNode.i < currentParent.i) {
currentParent.left = insertNode(currentParent.left, newNode);
}
return currentParent;
}
what do we call this in Java terms ?
You would need to create a copy of the original object.
One way to do it is with a copy constructor :
public Tree (Tree other) {
// copy all the properties of other to the new object
}
Then change
Tree t2 = t.add(6).add(7).add(6);
to
Tree t2 = new Tree(t).add(6).add(7).add(6);
Note that if the members of Tree include reference types (i.e. references to other objects), you must decide whether to create new copies of these objects too. If you copy just the references, you'll get a shallow copy of the original object, which could cause problems.
EDIT:
Since it appears Tree is an interface, you'll have to create a copy constructor in the class that implements it:
public Nodes (Tree other) {
// copy all the properties of other to the new object
}
Then you can create the copy directly:
Tree t2 = new Nodes(t).add(6).add(7).add(6);
or via a factory method:
Tree t2 = Trees.makeTree(t).add(6).add(7).add(6);
where makeTree is:
public static Tree makeTree(Tree source) {
Tree tree = new Nodes(source);
return tree;
}
Note that public Nodes (Tree other) is not exactly a copy constructor now - it's more general than a copy constructor, since it can accept any implementation of the Tree interface and create a new Nodes instance that contains the same data.
You would implement Tree as immutable (meaning a once instantiated object can not be changed) and create a new instance in add:
public Tree add(int node) {
// highly inefficient, assuming nodes are internally stored as an int array
// allocate new array + 1 size
int[] nodes = new int[this.nodes.length + 1];
// copy this tree's nodes
System.arraycopy(this.nodes, 0, nodes, 0, this.nodes.length);
// add new node
nodes[nodes.length - 1] = node;
// return new tree instance
return new Tree(nodes);
}

Sorting custom List Java

I have a custom generic linked list class called SLL. For the purpose of my program SLL is going to hold Word objects. In my Word class I have implemented the comparable interface, and defined three comparators. When I go to compile I get an error when trying to sort the custom list, using Collections.sort(). I cannot for the life of me figure out why. I have included some code below. The error message states:
//There is no suitable method found for sort(SLL<Word>, java.util.Comparator<Word>)
private static SLL<Word> wordList = new SLL<Word>();
//methods to populate custom generic list
private void printDescending ()
{
Collections.sort(wordList, Word.frequencyComp1);
System.out.println("10 Most Frequent");
printer(false);
}
My class declaration for SLL and a couple methods are as follows:
public class SLL <T extends Comparable <T>>
{
private Node<T> head , tail;
private int currentSize;
public SLL ()
{
this.head = null;
this.tail = null;
this.currentSize = 0;
}
public void add (Node<T> entry)
{
if (head == null)
{
Node<T> temp = entry;
head = temp;
tail = temp;
currentSize++;
}
else
{
Node<T> temp = entry;
tail.setNext(temp);
tail = temp;
currentSize++;
}
}
Any and all help would be greatly appreciated, I am on the last phase of my program :(
https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#sort(java.util.List)
According to this, your list(SLL) must have a List interface.
private static SLL<Word> wordList = new SLL<Word>();
As per your code SLL is class and wordList is class object with the reference of word class.
If you want use the sort method of Collection class the wordList object must be collection type object like below:
List<SLL<Word>> wordList = new ArrayList<SLL<Word>>();

Implementing the difference between two sorted Lists of comparable items in java

Implement a method in Java to compute the difference () between L1 and L2. L1 \ L2 = { x | x ∈ L1 and x ∉ L2 }.
This is my implementation so far:
public static <AnyType extends Comparable<? super AnyType>>
void difference(List<AnyType> L1, List<AnyType> L2, List<AnyType> Difference){
if(L1 == null){
Difference = null;
}
else if(L2 == null){
Difference = L1;
}
else if(L1.size()==0 || L2.size()==0){
Difference = L1;
}
else{
Iterator<AnyType> it1 =L1.listIterator();
Iterator<AnyType> it2 =L2.listIterator();
AnyType a = it1.next();
AnyType b = it2.next();
while(true){
if(a.compareTo(b)>0){
if(it2.hasNext()){
b = it2.next();
}
else{
Difference.add(a);
while(it1.hasNext()){
a = it1.next();
Difference.add(a);
}
break;
}
}
else if(a.compareTo(b)<0){
Difference.add(a);
if(it1.hasNext()){
a = it1.next();
}
else break;
}
else {
if(it1.hasNext()){
a =it1.next();
}
else break;
}
}
}
System.out.println("Difference Set: " + Arrays.toString(Difference.toArray()));
}
This is not the trivial solution which would be to implement two nested for loops and save to the result list the right elements, that solution is O(n^2).
Another possible solution is to search the second list using binary search, that algorithm would be O(n*Log(n))
The solution here implemented, attempts to go through the lists only once and finish in the first pass, this will be O(n) linear.
The algorithm works fine, however it feels like it could use some optimization still, it feels like spaghetti code lol. Any pointers that could help me to optimize this?
The first thing I see is that you perform a.compareTo(b) twice for each iteration through the loop. Instead, use compareTo once and store the result for use in both if statements.
Secondly, use for a consistent naming scheme like objA and iterA instead of a and it1. It'll just make it a little easier to follow. For that matter, don't be afraid of longer names. listA than l1 might be a couple extra characters, but it's worth it for readability. (Also, don't forget that you shouldn't start a variable with a capital letter, so L1 is doubly-uncool.)
Finally, comment comment comment. I know this algorithm, so I can follow the code pretty well, but it's far from self-documenting. Comment each if statement and loop to document what the condition is, why you're checking, and what you're doing with the results.
EDIT: I thought about this some more and as another alternative approach that is probably more optimal than my initial post you could take advantage of the hashCode method and HashMap implementation as follows:
public static <AnyType extends Comparable<? super AnyType>>
void difference(List<AnyType> L1, List<AnyType> L2, List<AnyType> Difference){
HashMap<AnyType,Boolean> map = new HashMap<AnyType,Boolean>();
for(AnyType item: L1){
map.put(item, true);
}
for(AnyType item: L2){
map.put(item, false);
}
Difference.clear();
for(AnyType item: map.keySet()){
if(map.get(item)){
Difference.add(item);
}
}
}
END EDIT
Not sure how optimized this is, but another approach would be to take advantage of the collections framework to do the heavy lifting for you if you create a wrapper class to define the equals method. I left in some System.out.println calls in case anyone wants to trace the logic.
import java.util.ArrayList;
import java.util.List;
public class ListDiff {
public static void main(String[] args) {
List<String> L1 = new ArrayList<String>();
L1.add("item1");
L1.add("item2");
L1.add("item3");
L1.add("item3"); //duplicate item intentional for demonstration
L1.add("item5");
List<String> L2 = new ArrayList<String>();
L2.add("item1");
L2.add("item3");
L2.add("item4");
List<String> strDiff = new ArrayList<String>();
difference(L1,L2,strDiff);
System.out.println("strDiff is: "+strDiff);
List<Integer> list3 = new ArrayList<Integer>();
list3.add(1);
list3.add(2);
list3.add(3);
list3.add(3); //duplicate item intentional for demonstration
list3.add(5);
List<Integer> list4 = new ArrayList<Integer>();
list4.add(1);
list4.add(3);
list4.add(4);
List<Integer> intDiff = new ArrayList<Integer>();
difference(list3,list4,intDiff);
System.out.println("intDiff is: "+intDiff);
}
public static <AnyType extends Comparable<? super AnyType>>
void difference(List<AnyType> L1, List<AnyType> L2, List<AnyType> Difference){
List<EqualityWrapper<AnyType>> list1 = new ArrayList<EqualityWrapper<AnyType>>();
for(AnyType item: L1){
EqualityWrapper<AnyType> wrappedItem = new EqualityWrapper<AnyType>(item);
list1.add(wrappedItem);
}
List<EqualityWrapper<AnyType>> list2 = new ArrayList<EqualityWrapper<AnyType>>();
for(AnyType item: L2){
EqualityWrapper<AnyType> wrappedItem = new EqualityWrapper<AnyType>(item);
list2.add(wrappedItem);
}
// System.out.println("list1: "+list1);
List<EqualityWrapper<AnyType>> diff = new ArrayList<EqualityWrapper<AnyType>>(list1);
// System.out.println("diff: "+diff);
// System.out.println("list2: "+list2);
diff.removeAll(list2);
// System.out.println("diff: "+diff);
Difference.clear();
for(EqualityWrapper<AnyType> item: diff){
AnyType unwrapped = item.getOrig();
Difference.add(unwrapped);
}
}
public static class EqualityWrapper<AnyType extends Comparable<? super AnyType>> {
private AnyType orig;
public EqualityWrapper(AnyType comparable){
orig = comparable;
}
#Override
public boolean equals(Object other){
if(other instanceof EqualityWrapper){
EqualityWrapper<AnyType> otherEqualityWrapper = (EqualityWrapper<AnyType>)other;
// System.out.println("Comparing "+orig+" with "+otherEqualityWrapper.getOrig());
return orig.compareTo(otherEqualityWrapper.getOrig()) == 0;
}
// System.out.println("returning false");
return false;
}
public AnyType getOrig(){
return orig;
}
#Override
public String toString(){
return orig.toString();
}
}
}
OUTPUT:
strDiff is: [item2, item5]
intDiff is: [2, 5]

Categories

Resources