I'm working on a project in which I'm supposed to develop a set of classes to implement a BST that allows me to code a word in Morse code and translate Morse code to alphanumeric format.
I've been provided with the following:
BST generic implementation -> https://pastebin.com/mGLY2V25
This class implements the following interface:
public interface BSTInterface<E> {
boolean isEmpty();
void insert(E element);
void remove(E element);
int size();
int height();
E smallestElement();
Iterable<E> inOrder();
Iterable<E> preOrder();
Iterable<E> posOrder();
Map<Integer, List<E>> nodesByLevel();
}
And so far I came up with the following:
class MorseTree extends BST<MorseNode> {
public MorseTree() {
init();
}
private void init() {
BufferedReader in;
InputStream inputStream = getClass().getResourceAsStream("/morse_V3.txt");
in = new BufferedReader(new InputStreamReader(inputStream));
insert(new MorseNode(new String[]{"start"}));
MorseNode last = root.getElement();
in.lines().forEach(line -> {
String[] temp = line.trim().replaceAll(" +", " ").split(" ");
MorseNode w = new MorseNode(temp);
for (int i = 0; i < temp[0].length(); i++) {
}
});
}
#Override
public void insert(MorseNode element) {
root = insert(element, root);
}
private Node<MorseNode> insert(MorseNode element, Node<MorseNode> node) {
if (node == null) {
return new Node<>(element, null, null);
}
}
}
public class MorseNode implements Comparable<MorseNode> {
private String morse;
private Character letter;
private String tipo;
public MorseNode(String[] word) {
this.morse = word[0];
this.letter = word[1].charAt(0);
this.tipo = word[2];
}
#Override
public int compareTo(MorseNode o) {
if (letter == o.letter) {
return 0;
}
}
#Override
public String toString() {
return Character.toString(letter);
}
}
(Pastebin)
To build the tree I'm supposed to read a csv/txt file and insert it. From what I've gathered the idea is that I should implement a compareTo method in class in a way that the provided insert method would automatically insert it.
That's my problem. For two weeks now I've been trying and I just can't get an idea on how to compare two Morse strings.
Any help or suggestions are appreciated!
Related
I try to compare different types with hamcrest. But I don't understand, how I have to build my own Matcher for the following problem:
String[] exp = new String[]{"x", "y", "z"};
DAO[] cur = getFromExternalWebservice();
Assert.assertThat("wrong strings", exp, Matchers.arrayContainingInAnyOrder(cur));
cur is an array of the following class:
class DAO {
public String id;
public String name;
}
The test above should actually compare the Strings within exp and the name property of the DAO objects within the array cur. I cannot change something on DAO (like adding a toString() method).
I can transform the results from the webservice into a names array, which I send to the Matcher like this:
String names[] = new String[cur.length];
for (int i = 0; i < cur.length; i++) {
names[i] = cur[i].name;
}
Assert.assertThat("wrong strings", exp, Matchers.arrayContainingInAnyOrder(names));
But this is ugly, how I can build a Matcher which compares the Strings without any copy of data?
I have implemented a first idea:
public class IsIn extends BaseMatcher<String> {
class DAOIterator implements Iterable<String>, Iterator<String> {
private final DAO[] collection;
private int idx;
public DAOIterator(DAO[] elements) {
this.collection = elements;
idx = 0;
}
#Override
public boolean hasNext() {
return (this.collection.length > this.idx);
}
#Override
public String next() {
return this.collection[this.idx++].name;
}
#Override
public Iterator<String> iterator() {
return new DAOIterator(this.collection);
}
}
private final DAO[] collection;
public IsIn(DAO[] elements) {
this.collection = elements;
}
#Override
public boolean matches(Object o) {
for (DAO d : this.collection) {
if (o == null ? d.name == null : o.equals(d.name)) {
return true;
}
}
return false;
}
#Override
public void describeTo(Description buffer) {
buffer.appendText("one of ");
buffer.appendValueList("{", ", ", "}", new DAOIterator(this.collection));
}
}
Call this on JUnit testcase:
String[] exp = new String[]{"x", "y", "z"};
DAO[] cur = getFromExternalWebservice();
Assert.assertThat("wrong strings", Arrays.asList(exp), Matchers.everyItem(new IsIn(cur)));
Hi,
Update: Thanks for all your suggestion
assuming that, this exercise it's like a rebus,
I have a list of numbers made with the concept of Cons and Nil,
List l = new Cons(**3**, new Cons(**2**,new Cons(**1**, new
Cons(**4**, new Cons(**1**, new Nil())))));
and I want to count how many of them are immediately followed by a lower number, recursively.
For example
[5,0,5,3].count() == 2, [5,5,0].count() == 1
The count() method is made by me (it cannot have any parameters), the rest is default, and I can't make and other method or use already defined one's like add(),size()...
The "NEXT" must have the next value after the current elem but I can't get a solution.
Any solutions are welcome.
abstract class List {
public abstract boolean empty();
public abstract int first();
public abstract int count();
}
class Cons extends List {
private int elem;
private List next;
public Cons(int elem, List next) {
this.elem = elem;
this.next = next;
}
public boolean empty(){
return false;
}
public int first(){
return elem;
}
#Override
public int count() {
if(elem>NEXT) {
return 1 + next.count();
}else {
return next.count();
}
}
```![enter image description here](https://i.stack.imgur.com/kWo0v.jpg)
The following code will create a recursive list with N elements with N value being defined by the size of the amount of elements found in the int array called elements in RecursiveList class. Call the startRecursion() method to create a recursive list with the defined elements and call count() to get the amount of elements in the array that are immediately followed by a lower number.
Main Class
This your application entry point:
public static void main(String[] args) {
int count = RecursiveList.startRecursion().count();
System.out.printf("List has %d recursive elements", count);
}
RecursiveList Class
abstract class RecursiveList {
protected static int index = -1;
protected static int[] elements = new int[]{ 5,2,1,4,3,2,6 };
public static RecursiveList startRecursion() {
return new Cons();
}
public abstract boolean empty();
public abstract int count();
public abstract Integer getElement();
public static int incIndex() {
return index += 1;
}
}
Cons Class
public class Cons extends RecursiveList {
private static int result;
private final Integer elem;
private final RecursiveList prev;
private final RecursiveList next;
private Cons(Cons parent) {
prev = parent;
elem = incIndex() < elements.length ? elements[index] : null;
System.out.printf("Creating new Cons with element %d(%d)%n", elem, index);
next = elem != null ? new Cons(this) : null;
}
Cons() {
this(null);
}
public boolean empty() {
return false;
}
#Override
public /*#Nullable*/ Integer getElement() {
return elem;
}
#Override
public int count() {
if (elem != null)
{
if (prev != null && elem < prev.getElement())
result += 1;
if (next != null) {
return next.count();
}
}
return result;
}
}
EDIT
Alright here is the answer you were actually looking for. This completely conforms to the limitations imposed on this exercise that you provided. The solution uses pure Java, neither the class nor any of it's method or field declarations were modified in any way and no such new elements were added. I've only added the implementation where the exercise said you should.
Main Class
public static void main(String[] args) {
List l = new Cons(3, new Cons(2,new Cons(1, new
Cons(4, new Cons(1, new Nil())))));
assert l.count() == 3;
l = new Cons(5, new Nil());
assert l.count() == 0;
l = new Cons(5, new Cons(5, new Cons(0, new Nil())));
assert l.count() == 1;
l = new Cons(5, new Cons(0, new Cons(5, new Cons(3, new Nil()))));
assert l.count() == 2;
System.out.println("All tests completed successfully!");
}
Cons Class
import java.util.NoSuchElementException;
public class Cons extends List {
private int elem;
private List next;
public Cons(int elem, List next) {
this.elem = elem;
this.next = next;
}
public boolean empty()
{ return false; }
public int first()
{ return elem; }
public int count()
{
try {
if (first() > next.first()) {
return 1 + next.count();
}
else return next.count();
}
catch (NoSuchElementException e) {
return 0;
}
}
}
Nil Class
import java.util.NoSuchElementException;
public class Nil extends List {
public boolean empty()
{ return true; }
public int first()
{ throw new NoSuchElementException(); }
public int count()
{
throw new IllegalAccessError();
}
}
public int NEXT(){
if(next!=null)
return next.first()
else
throw new Exception("No next element")
}
Here is my class:
public class LinkedListSet implements Set {
private class Node //much easier as a private class; don't have to extend
{
private int data;
private Node next;
public Node (){}
public Node (int x)
{
data = x;
}
public int data()
{
return data;
}
public Node next()
{
return next;
}
}
private Node first;
private int Size;
private int whichList; //used to identify the particular LL object
Here is my interface:
public interface Set {
public boolean isEmpty();
public void makeEmpty();
public boolean isMember(int x);
public void add(int x);
public void remove(int y);
public void union(Set other, Set result);
public void intersection (Set other, Set result);
public void difference (Set other, Set result);
#Override
public String toString();
#Override
public boolean equals(Object other);
public void setList(int i); //i added this to use it as an identifier for each
//list element in the set array
public String getListId(); //these two extra methods make life easier
}
I have a method like this (in the LinkedListSet class):
public void difference (Set other, Set result)
{
if (other.isEmpty())
{
System.out.println("The set is empty before cast");
}
LinkedListSet othr = (LinkedListSet) other;
LinkedListSet res = (LinkedListSet) result;
if (this.isEmpty() || othr.isEmpty())
{
if (othr.isEmpty())
System.out.println("The set is empty after cast");
if (this.isEmpty())
System.out.println("This is also empty");
return;
}
differenceHelper(this.first, othr.first, res);
result = res;
}// the print statements were added for debugging
The problem is, in the above method I am unable to cast the Set Other into its linked list implementation. When I call this method in the main program, the parameter is actually of type linked list (so I don't get any errors obviously).
However, all the instance variables are null. The list is empty before and after I cast it (when it actually isn't empty). I know this is because the interface doesn't include any information about the Nodes, but is there anything I can do other than editing the interface to incorporate the Node?
I hope I've made this clear enough. Any help would be appreciated.
edit:
In the main program I created an array of Sets.
Set[] sets = new Set[7];
for (int i = 0; i< sets.length; i++) //initialize each element
{
sets[i] = new LinkedListSet();
}
each list has nodes with data values which are added on later on in the code...
then I call the difference method.
sets[0].difference(sets[1], sets[4])
sets[1].isEmpty returns true for some reason (even though it is not).
If I were to do something like:
System.out.println(sets[1].first.data()) I would have no problem whatsoever.
For some reason all the values become null when the parameters are passed to the difference method.
public boolean isEmpty()
{
return first == null;
}
I tested what you are trying to do with the following code and I see no problems:
import org.junit.Test;
public class RandomCastTest {
public interface Set {
boolean isEmpty();
void add(int x);
void difference(Set other, Set result);
#Override
String toString();
#Override
boolean equals(Object other);
}
public class LinkedListSet implements Set {
private class Node //much easier as a private class; don't have to extend
{
private int data;
private Node next;
public Node() {
}
public Node(int x) {
data = x;
}
public int data() {
return data;
}
public Node next() {
return next;
}
public void next(Node node) {
next = node;
}
}
private Node first;
private int Size;
private int whichList; //used to identify the particular LL object
#Override
public boolean isEmpty() {
return first == null;
}
#Override
public void add(int x) {
Node node = new Node(x);
if (first == null) {
first = node;
} else {
Node currentNode;
Node nextNode = first;
do {
currentNode = nextNode;
nextNode = currentNode.next();
} while (nextNode != null);
currentNode.next(node);
}
Size++;
}
#Override
public void difference(Set other, Set result) {
if (other.isEmpty()) {
System.out.println("The set is empty before cast");
}
LinkedListSet othr = (LinkedListSet) other;
LinkedListSet res = (LinkedListSet) result;
if (this.isEmpty() || othr.isEmpty()) {
if (othr.isEmpty())
System.out.println("The set is empty after cast");
if (this.isEmpty())
System.out.println("This is also empty");
return;
}
result = res;
}
}
#Test
public void test() {
Set[] sets = new Set[7];
for (int i = 0; i < sets.length; i++) {
sets[i] = new LinkedListSet();
}
for (int i = 0; i < 5; i++) {
sets[1].add(i);
}
for (int i = 5; i < 10; i++) {
sets[0].add(i);
}
sets[0].difference(sets[1], sets[4]);
// ... find difference
}
}
To simplify I removed unimplemented methods from the interface. Also added the add method implementation. Please see if it works for you.
just a quick question. I have a jar file and I want to integrate it within my project. The decompiled version of the jar file looks like this:
public abstract class SinglyLinkedList
protected SinglyLinkedList.Item head;
public void addFront(String s) {
if (head == null) {
head = new SinglyLinkedList.Item(s);
}
else {
SinglyLinkedList.Item insert = new SinglyLinkedList.Item(s);
next = head;
head = insert;
}
}
public void add(String[] array) { String[] arrayOfString;
int j = (arrayOfString = array).length; for (int i = 0; i < j; i++)
{ String s = arrayOfString[i];
addFront(s);
}
}
public String toString()
{
if (head == null) {
return "empty list";
}
String s = "";
for (SinglyLinkedList.Item helper = head; next != null; helper = next) {
s = String.valueOf(s) + value + ", ";
s = String.valueOf(s) + value;
return s;
}
public abstract void sort();
protected class Item
{
public Item next;
public String value;
public Item(String value) {
this.value = value;
}
}
}
Now I want to create a new linked list in my other class, but this doesnt work:
private SinglyLinkedList linkedlist;
public SelectionSortableList(){
this.linkedlist = new SinglyLinkedList();
}
He cannot instantiate it. Can please somebody tell me why he don't want to instantiate it? Thank you in beforehand.
public abstract class SinglyLinkedList
Because this is an abstract class. abstract classes cannot be instantiated.
You need to extend it and implement the following abstract method:
public abstract void sort();
Once you extend the class all the non-private method will be directly accessible into your super class.
Your class should be like this:
class SelectionSortableList extends SinglyLinkedList {
#Override
public void sort() {
// provide you implementation here.
}
}
public class ContactList {
private ContactNode head;
private ContactNode last;
public ContactNode current;
public ContactList value;
public ContactList() {}
public void addNode(ContactNode input) {
if (this.head == null) {
this.head = input;
this.last = input;
} else last.setNext(input);
input.setPrev(last);
this.last = input;
}
public void traverse() {
System.out.println();
current = this.head;
while (current != null) {
System.out.print(current.getName() + " ");
System.out.println("");
current = current.getNext();
}
System.out.println();
}
public void insertNewFirstNode(String value) {
ContactNode newNode = new ContactNode(value);
head = newNode;
if (last == null) {
last = head;
}
}
public void sort() {
ContactList sorted = new ContactList();
current = head;
while (current != null) {
int index = 0;
if ((current.getName() != null)) {
index = this.current.getName().compareTo(current.getName());
if (index == 1) {
sorted.insertNewFirstNode(current.getName());
}
current = current.getNext();
} else if ((current != null)) {
System.out.print(sorted + "\n");
}
}
} // end contactList
Main Method:
import java.util.Scanner;
import java.io.FileReader;
import java.io.FileNotFoundException;
public class ContactMain {
public static void main(String[] args) {
try {
FileReader filepath = new FileReader("data1.txt");
Scanner k = new Scanner(filepath);
ContactList myList = new ContactList();
while (k.hasNextLine()) {
String i = k.nextLine();
myList.addNode(new ContactNode(i));
}
myList.traverse();
myList.sort();
myList.traverse();
} catch (FileNotFoundException e) {
System.out.println("File Not Found. ");
}
}
}
Node Class:
public class ContactNode {
private String name;
public int index;
private ContactNode prev;
public ContactNode next;
ContactNode(String a) {
name = a;
index = 0;
next = null;
prev = null;
}
public ContactNode getNext() {
return next;
}
public ContactNode getPrev() {
return prev;
}
public String getName() {
return name;
}
public int getIndex() {
return index;
}
public void setNext(ContactNode newnext) {
next = newnext;
}
public void setPrev(ContactNode newprevious) {
prev = newprevious;
}
public void setName(String a) {
name = a;
}
public void setIndex(int b) {
index = b;
}
}
I am making a program for fun that reads in contact information from a text file and puts them into a Linked List. I want to create a sort() method to sort each node or name alphabetically. I've done a good amount of research and my method only prints code like: ContactList#282c0dbe, by as many lines as my text file.
what is ContactList#282c0dbe?
It is class name follow by at sign and hash code at the end, hash code of the object.All classes in Java inherit from the Object class, directly or indirectly . The Object class has some basic methods like clone(), toString(), equals(),.. etc. The default toString() method in Object prints “class name # hash code”.
What is the solution?
You need to override toString method in ContactList class because it is going to give you clear information about the object in readable format that you can understand.
The merit about overriding toString:
Help the programmer for logging and debugging of Java program
Since toString is defined in java.lang.Object and does not give valuable information, so it is
good practice to override it for subclasses.
#override
public String toString(){
// I assume name is the only field in class test
return name + " " + index;
}
For sorting, you should implement Comparator interface since your object does not have natural ordering. In better sense, if you want to define an external controllable ordering behavior, this can override the default ordering behavior
read more about Comparator interface
You need custom Comparator for sorting, and to pretty print your List you need to implement toString() in ContactList class