Heap Book Box Packing - java

I am attempting to write a program that reads in an order of books, stores them in a heap and implements a greedy algorithm to pack the books into boxes efficiently based on weight;
I am having trouble with implementing the heap correctly.
The method I am using to add to the Heap is called addLastChild(). It should find the next spot in the heap and insert the new book and restructure according to its weight.
here is the add code:
public void addLastChild(Book newBook)
{
Book[] pathList = new Book[30];
int tracker = 0;
int cnt = BookCnt+1;
String path = "";
while(cnt >= 1)
{
path = (cnt %2) + path;
cnt = cnt / 2;
}
Book c = root;
if(root!=null)
{
pathList[tracker]=root;
tracker++;
}
for(int i = 1; i < path.length()-1; i++){
if(path.charAt(i)== '0') {
c = c.left;
pathList[tracker]=c;
tracker++;
} else {
c = c.right;
pathList[tracker]=c;
tracker++;
}
}
if(path.length() == 1)
{
root = newBook;
}
else if(path.charAt(path.length()-1)== '0') {
c.left = newBook;
pathList[tracker]=c.left;
tracker++;
}
else
{
c.right = newBook;
pathList[tracker]=c.right;
tracker++;
}
BookCnt++;
boolean doTrickle = false;
if(tracker>=2)
{
doTrickle = true;
}
while(doTrickle == true)
{
Book temp = new Book(pathList[tracker-2].refNumber, pathList[tracker-2].weight, pathList[tracker-2].title, null,null);
//int refNumber, int weight, String title, Book left, Book right
print(root," ");
if(pathList[tracker-1].weight > pathList[tracker-2].weight)
{
pathList[tracker-2].refNumber=pathList[tracker-1].refNumber;
pathList[tracker-2].title=pathList[tracker-1].title;
pathList[tracker-2].weight=pathList[tracker-1].weight;
if(pathList[tracker-2].left == pathList[tracker-1])
{
pathList[tracker-2].left = temp;
}
if(pathList[tracker-2].right == pathList[tracker-1])
{
pathList[tracker-2].right = temp;
}
tracker--;
System.out.println("we trickled");
print(root," ");
}
else
{
doTrickle =false;
}
}
}
The 2 methods that I am using to remove from the Heap are removeLastChild() and remove() the removeLastChild() method returns the last book in the Heap, and the remove() should return the book with the largest weight and replace the root with the last Book, then restructure the heap accordingly.
Here is the removal Code that is giving me trouble:
Book removeLastChild() {
int cnt = BookCnt;
String path = "";
while(cnt >= 1)
{
path = (cnt %2) + path;
cnt = cnt / 2;
}
Book returnBook = null;
Book c = root;
for(int i = 1; i < path.length()-1; i++){
if(path.charAt(i)== '0') {
c = c.left;
} else {
c = c.right;
}
}
if(path.length() == 1)
{
returnBook = root;
root = null;
}
else if(path.charAt(path.length()-1)== '0') {
returnBook = c.left;
c.left = null;
}
else
{
returnBook = c.right;
c.right = null;
}
BookCnt--;
return returnBook;
}
Book remove()
{
Book largest =root;
root = removeLastChild();
if(largest.left!= null)
{
root.left = largest.left;
}
if(largest.right!= null)
{
root.right = largest.right;
}
Book cur = root;
if(root!= null)
{
while(cur.left !=null && cur.right!= null)
{
if(cur.weight<cur.left.weight || cur.weight<cur.right.weight)
{
Book temp = new Book(cur.refNumber, cur.weight, cur.title, null, null);
//int refNumber, int weight, String title, Book left, Book right
if(cur.left.weight>cur.right.weight)
{
cur.refNumber = cur.left.refNumber;
cur.title = cur.left.title;
cur.weight = cur.left.weight;
cur.left.refNumber = temp.refNumber;
cur.left.weight = temp.weight;
cur.left.title = temp.title;
cur = cur.left;
}
else
{
cur.refNumber = cur.right.refNumber;
cur.title = cur.right.title;
cur.weight = cur.right.weight;
cur.right.refNumber = temp.refNumber;
cur.right.weight = temp.weight;
cur.right.title = temp.title;
cur = cur.right;
}
}
else
{
return largest;
}
}
}
return largest;
}
Thanks for the Help!
I'm happy to clarify anything that I didn't communicate clearly.

If I might suggest an alternative to your heap implementation, and given your objective of the greedy algorithm for the Knapsack problem, why no not simply use a PriorityQueue?
From the documentation: "An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time (...)"
If your book class implements the Comparable interface like this (the Book in the example is very simplified):
class Book implements Comparable<Book>{
public String title;
public int weight;
public Book(int weight, String title) {
this.weight = weight;
this.title = title;
}
#Override
public int compareTo(Book anotherBook) {
return weight - anotherBook.weight;
}
}
The natural ordering of your books should go from the book with the least weight to the book with the most weight.
Using the Book class in a priority queue:
public static void main(String[] args) {
Book book1 = new Book(10,"a");
Book book2 = new Book(11,"b");
Book book3 = new Book(20,"c");
Book book4 = new Book(20,"d");
Book book5 = new Book(11,"e");
PriorityQueue<Book> bookQueue = new PriorityQueue<Book>();
bookQueue.add(book1);
bookQueue.add(book2);
bookQueue.add(book3);
bookQueue.add(book4);
bookQueue.add(book5);
while(!bookQueue.isEmpty()){
Book book = bookQueue.poll();
System.out.println(book.title + " - " + book.weight);
}
}
You should be able to iterate the books the way you need to put them in your boxes.

Related

How to calculate the median for every insertion in a priority queue in java?

I read objects(Movies) from a file and i compare based on their likes. I want to get the median after every Movie insertion in the queue. In the code below there are :
Movie method compareTo
PQ insert and getMax methods with swim and sink
Main class
I'm creating both priority queues for higher and less objects than median, but i don't know how to dynamically calculate it. Every movie element is created with id, title, likes in this order.
public int compareTo(Movie m) {
if (this.likes == m.likes) {
return -this.title.compareTo(m.title);
} else if (this.likes > m.likes) {
return 1;
} else {
return -1;
}
}
public class PQ {
private Movie[] pq;
private int size;
public PQ(int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException();
}
this.pq = new Movie[capacity + 1];
this.size = 0;
}
public void insert(Movie movie) {
if (this.size == this.pq.length - 1) {
throw new IllegalArgumentException();
}
if (movie == null) {
throw new IllegalArgumentException();
}
this.size++;
this.pq[this.size] = movie;
swim(this.size);
}
public void swim(int i) {
while (i > 1) {
int p = i / 2;
int result = this.pq[p].compareTo(this.pq[i]);
if (result <= 0)
return;
swap(i, p);
i = p;
}
}
public Movie Max() {
if (this.size == 0)
throw new IllegalArgumentException();
return this.pq[1];
}
public Movie getMax() {
if (this.size == 0)
throw new IllegalArgumentException();
Movie m = this.pq[1];
if (this.size > 1)
this.pq[1] = this.pq[this.size];
this.pq[this.size--] = null;
sink(1);
return m;
}
private void sink(int i) {
int left = 2 * i;
int right = left + 1;
int max = left;
while (left <= this.size) {
if (right <= this.size) {
max = this.pq[right].compareTo(this.pq[left]) < 0 ? right
: left;
}
if (this.pq[max].compareTo(this.pq[i]) >= 0)
return;
swap(i, max);
i = max;
left = 2 * i;
right = left + 1;
max = left;
}
}
private void swap(int i, int j) {
Movie tmp = pq[i];
pq[i] = pq[j];
pq[j] = tmp;
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Dynamic_Median {
public static void main(String[] args) {
BufferedReader br = null;
PQ higher_median = new PQ(4);
PQ less_median = new PQ(4);
Movie median = null;
try { // try to read the file
br = new BufferedReader(new FileReader("movies.txt"));
String line;
String title = "";
int id = 0;
int likes = 0;
while ((line = br.readLine()) != null) {
line = line.trim();
line = line.replaceAll("/t", "");
String[] tokens = line.split(" "); // store every token in an
// String array
id = Integer.parseInt(tokens[0]);
likes = Integer.parseInt(tokens[tokens.length - 1]);
for (int i = 1; i < tokens.length - 1; i++) {
title = title + " " + tokens[i];
}
title = "";
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ki esy re kopela mou teleftaia mera ths prothesmias thymithikes na rwthseis? :P

Wacky Linked List behavior Java Eclipse Mars.1

The full code is a 2-3 tree implementation that requires me to be able to search for a book by any key(ISSN, Author[0], Author[1], Author[0] + "," + Author[1], or Title) The tree works by creating 5 copies of each book, each designated with one of the keys previously mentioned, and inserting them into their respective leaves. If a new book being inserted matches a key that has already been inserted into the tree (ie., James Henry, and James Joyce both would have a copy of their books inserted into the tree with key "james"), then instead of that new book being added into a leaf node at the bottom of the tree, it is added into a linked list inside of the node that already contains a copy all books with key == "james".
Class Tree23:
package tree23;
import bookClasses.*;
/**
* #author Chris
* #usage This Class builds a 2-3 tree that sorts Book entries based on ISSN value
*/
public class Tree23 {
public Node23 Root;
// PUBLIC FUNCTIONS //
public Tree23(){
Root = new Node23(true);
}
public void Insert(int issn, String title, String author){
String issnKey = null;
String titleKey = null;
String authorKey = null;
String author0Key = null;
String author1Key = null;
issnKey = String.valueOf(issn);
titleKey = title.toLowerCase();
authorKey = author.toLowerCase();
if(author.split(",").length == 2){
author0Key = author.split(",")[0].toLowerCase();
author1Key = author.split(",")[1].toLowerCase();
}
Book[] newBooks = new Book[5];
for(int i = 0; i < 5; i++){
newBooks[i] = new Book(issn, title, author);
}
InsertByKey(newBooks[0], issnKey);
InsertByKey(newBooks[1], titleKey);
InsertByKey(newBooks[2], authorKey);
if(author.split(",").length == 2){
InsertByKey(newBooks[3], author0Key);
InsertByKey(newBooks[4], author1Key);
}
}
public BookList GetBooksByAttribute(char attribute, String key){
BookList matches = null;
switch(attribute){
case 'i':
matches = GetBooksByISSN(Integer.valueOf(key));
break;
case 'n':
matches = GetBooksByAuthor(key.toLowerCase());
break;
case 't':
matches = GetBooksByTitle(key.toLowerCase());
break;
default:
break;
}
return matches;
}
// PRIVATE FUNCTIONS //
/*Insert Functions*/
private void InsertByKey(Book newBook, String key){
if(key.compareTo("james") == 0){
if(newBook.Title.toLowerCase().compareTo("finnegans wake") == 0){
System.out.print("");
}
}
//check for a node with matching key
Node23 targetNode = GetNodeByKey(Root, key);
//else find leaf for insert
if(targetNode == null){
targetNode = GetLeafByKey(Root, key);
}
//insert into target node
targetNode.AddBook(newBook, key);
if(key.compareTo("james") == 0){
System.out.print("");
}
if(targetNode.GetSize() == 3){
BalanceNodeOverflow(targetNode);
}
}
/*Search Functions*/
private BookList GetBooksByKey(Node23 n, String key){
BookList bList = null;
int match = n.GetMatchingBookListByKey(key);
if(match != -1){
bList = n.Books[match];
}
else{
int nextChild = DetermineNextTraversal(n, key);
bList = GetBooksByKey(n.Children[nextChild], key);
}
return bList;
}
private Node23 GetSuccessorLeaf(Node23 n, int index){
Node23 leaf = n.Children[index + 1];
while(!leaf.IsLeaf()){
leaf = leaf.Children[0];
}
return leaf;
}
private BookList GetBooksByISSN(int issn){
BookList keyMatches = GetBooksByKey(Root, String.valueOf(issn));
BookList issnMatches = null;
if(keyMatches != null){
issnMatches = keyMatches.GetBooksByISSN(issn);
}
return issnMatches;
}
private BookList GetBooksByAuthor(String author){
BookList keyMatches = GetBooksByKey(Root, String.valueOf(author));
BookList authorMatches = null;
if(keyMatches != null){
authorMatches = keyMatches.GetBooksByAuthor(author);
}
return authorMatches;
}
private BookList GetBooksByTitle(String title){
BookList keyMatches = GetBooksByKey(Root, String.valueOf(title));
BookList titleMatches = null;
if(keyMatches != null){
titleMatches = keyMatches.GetBooksByTitle(title);
}
return titleMatches;
}
private Node23 GetLeafByKey(Node23 n, String key){
//assumes that there is no node matching key, traverses from root to leaf node by key
//return key
Node23 leaf = n;
if(!n.IsLeaf()){
int nextChild = n.GetNextChildByKey(key);
leaf = GetLeafByKey(n.Children[nextChild], key);
}
return leaf;
}
private Node23 GetNodeByKey(Node23 n, String key){
Node23 match = null;
int nextChild;
int matchingBookList = n.GetMatchingBookListByKey(key);
if(matchingBookList >= 0){
match = n;
}
else{
nextChild = n.GetNextChildByKey(key);
if(nextChild != -1){
match = GetNodeByKey(n.Children[nextChild], key);
}
}
return match;
}
private int DetermineNextTraversal(Node23 n, String key){
int nextChild;
if(n.IsLeaf()){
nextChild = -1;
}
else if(n.GetSize() == 0){
nextChild = -1;
}
else if(n.GetSize() == 1){
if(n.Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else{
nextChild = 1;
}
}
else{
if(n.Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else if(n.Books[1].CompareTo(key) > 0){
nextChild = 1;
}
else{
nextChild = 2;
}
}
return nextChild;
}
/*Delete Functions*/
private void DeleteBookFromTree(Book b){
Node23 match;
int originalSize;
/*findNodeMatchingISSN*/
match = GetNodeByKey(Root, String.valueOf(b.ISSN));
originalSize = match.GetSize();
match.RemoveMatchingBook(b, String.valueOf(b.ISSN));
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
/*author[0]*/
match = GetNodeByKey(Root, b.Author[0]);
originalSize = match.GetSize();
match.RemoveMatchingBook(b, b.Author[0]);
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
if(b.Author.length == 2){
/*author[1]*/
match = GetNodeByKey(Root, b.Author[1]);
originalSize = match.GetSize();
match.RemoveMatchingBook(b, b.Author[1]);
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
/*author[0],author[1]*/
match = GetNodeByKey(Root, new String(b.Author[1] + "," + b.Author[2]));
originalSize = match.GetSize();
match.RemoveMatchingBook(b, new String(b.Author[1] + "," + b.Author[2]));
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
}
/*title*/
match = GetNodeByKey(Root, b.Title);
originalSize = match.GetSize();
match.RemoveMatchingBook(b, b.Author[1]);
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
}
/*Tree Balancing Functions*/
private void BalanceNodeOverflow(Node23 fullNode){
Node23[] splitNodes;
if(fullNode == Root){
Node23 newRoot = new Node23(false);
fullNode.Parent = newRoot;
splitNodes = fullNode.SplitNode();
fullNode.Parent.AddBookList(fullNode.RemoveBookList(0));;
newRoot.AddSplitNodeChildAt(0, splitNodes);
Root = newRoot;
}
else{
int position = fullNode.WhichChildAmI();
splitNodes = fullNode.SplitNode();
fullNode.Parent.AddBookList(fullNode.RemoveBookList(0));
fullNode.Parent.AddSplitNodeChildAt(position, splitNodes);
if(fullNode.Parent.GetSize() == 3){
BalanceNodeOverflow(fullNode.Parent);
}
}
}
private void RotateLeft1To0(Node23 parent){
Node23[] children = parent.Children;
children[0].AddBookList(parent.RemoveBookList(0));
parent.AddBookList(children[1].RemoveBookList(0));
children[1].ShiftBooksLeftInto(0);
}
private void RotateLeft2To1(Node23 parent){
Node23[] children = parent.Children;
children[1].AddBookList(parent.RemoveBookList(1));
parent.AddBookList(children[2].RemoveBookList(0));
children[2].ShiftBooksLeftInto(0);
}
private void RotateRight0To1(Node23 parent){
Node23[] children = parent.Children;
children[1].AddBookList(parent.RemoveLeftMostBookList());
parent.AddBookList(children[0].RemoveRightMostBookList());
}
private void RotateRight1To2(Node23 parent){
Node23[] children = parent.Children;
children[2].AddBookList(parent.RemoveRightMostBookList());
parent.AddBookList(children[1].RemoveRightMostBookList());
}
private void BalanceNodeUnderflow(Node23 n){
Node23 leaf;
int emptyPosition = n.FirstNullBookList();
if(!n.IsLeaf()){
leaf = GetSuccessorLeaf(n, emptyPosition);
n.AddBookList(leaf.RemoveBookList(0));
}
else{
leaf = n;
}
if(leaf.GetSize() == 0){
FillHole(leaf);
}
}
private void RedistributeParent3(Node23 hole, int holePosition){
Node23 parent = hole.Parent;
Node23[] siblings = parent.Children;
switch(holePosition){
case 0:
if(siblings[1].GetSize() == 2){
RotateLeft1To0(parent);
if(!hole.IsLeaf()){
hole.AddChildAt(1, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
}
}
else if(siblings[2].GetSize() == 2){
RotateLeft1To0(parent);
RotateLeft2To1(parent);
if(!hole.IsLeaf()){
hole.AddChildAt(1, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
siblings[2].ShiftChildrenLeftInto(0);
}
}
else{
RotateLeft1To0(parent);
hole.AddBookList(parent.RemoveBookList(0));
parent.ShiftBooksLeftInto(0);
siblings[1].AddBookList(siblings[2].RemoveBookList(0));
if(!hole.IsLeaf()){
hole.AddChildAt(1, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
hole.AddChildAt(2, siblings[1].RemoveLeftMostChild());
siblings[1].AddChildAt(0, siblings[2].RemoveLeftMostChild());
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
}
parent.RemoveRightMostChild();
}
break;
case 1:
if(siblings[0].GetSize() == 2){
RotateRight0To1(parent);
if(!hole.IsLeaf()){
siblings[1].ShiftChildrenRightInto(1);
siblings[1].AddChildAt(0, siblings[0].RemoveRightMostChild());
}
}
else if(siblings[2].GetSize() == 2){
RotateLeft2To1(parent);
if(!hole.IsLeaf()){
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
siblings[2].ShiftBooksLeftInto(0);
}
}
else{
RotateLeft2To1(parent);
siblings[1].ShiftBooksLeftInto(0);
RotateLeft1To0(parent);
parent.ShiftBooksLeftInto(0);
if(!hole.IsLeaf()){
siblings[0].AddChildAt(2, siblings[1].RemoveLeftMostChild());
siblings[1].AddChildAt(0, siblings[2].RemoveLeftMostChild());
siblings[1].AddChildAt(1, siblings[2].RemoveRightMostChild());
}
parent.RemoveRightMostChild();
}
break;
case 2:
if(siblings[0].GetSize() == 2){
RotateRight1To2(parent);
RotateRight0To1(parent);
if(!hole.IsLeaf()){
siblings[2].ShiftChildrenRightInto(1);
siblings[2].AddChildAt(0, siblings[1].RemoveRightMostChild());
siblings[1].ShiftBooksRightInto(1);
siblings[1].AddChildAt(0, siblings[0].RemoveRightMostChild());
}
}
else if(siblings[1].GetSize() == 2){
RotateRight1To2(parent);
if(!hole.IsLeaf()){
siblings[2].ShiftChildrenRightInto(1);
siblings[2].AddChildAt(0, siblings[1].RemoveRightMostChild());
}
}
else{
RotateLeft1To0(parent);
siblings[1].AddBookList(parent.RemoveRightMostBookList());
if(!hole.IsLeaf()){
siblings[0].AddChildAt(2, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
}
parent.RemoveRightMostChild();
}
break;
default:
break;
}
}
private void RedistributeParent2(Node23 hole, int holePosition){
Node23 parent = hole.Parent;
Node23[] siblings = parent.Children;
switch(holePosition){
case 0:
hole.AddBookList(parent.RemoveBookList(0));
parent.AddBookList(siblings[1].RemoveBookList(0));
siblings[1].ShiftBooksLeftInto(0);
break;
case 1:
hole.AddBookList(parent.RemoveBookList(0));
parent.AddBookList(siblings[0].RemoveBookList(1));
break;
default:
break;
}
}
private void Merge(Node23 hole, int holePosition){
Node23 parent = hole.Parent;
Node23[] sibling = parent.Children;
if(holePosition == 0){
sibling[0].AddBookList(sibling[1].RemoveBookList(0));
}
sibling[0].AddBookList(parent.RemoveBookList(0));
if(!hole.IsLeaf()){
sibling[0].AddChildAt(1, sibling[1].RemoveLeftMostChild());
sibling[0].AddChildAt(2, sibling[1].RemoveRightMostChild());
}
parent.RemoveRightMostChild();
if(parent.GetSize() == 0){
BalanceNodeUnderflow(parent);
}
}
private void FillHole(Node23 hole){
Node23[] siblings;
Node23 parent;
int holePosition;
if(hole == Root){
Root = hole.Children[0];
}else{
parent = hole.Parent;
siblings = parent.Children;
holePosition = hole.WhichChildAmI();
if(parent.GetSize() == 2){
RedistributeParent3(hole, holePosition);
}
else{
if(siblings[0].GetSize() == 2 || siblings[1].GetSize() == 2){
RedistributeParent2(hole, holePosition);
}else{
Merge(hole, holePosition);
}
}
}
}
}
package tree23;
import bookClasses.*;
/**
* #Node
*This Node is designed for a 2-3 Tree.
*The Node holds two Book objects and points to three children nodes of the same type.
*The node is also designed to hold an overflow Book and overflow child, until the node is split.
*/
public class Node23 {
public BookList[] Books;
private boolean isLeaf;
private int size;
public Node23 Parent;
public Node23[] Children;
//Constructors
public Node23(boolean isleaf){
Books = new BookList[3];
Children = new Node23[4];
isLeaf = isleaf;
size = 0;
}
public Node23[] SplitNode(){
Node23[] splitNodes = new Node23[2];
splitNodes[0] = new Node23(isLeaf);
splitNodes[1] = new Node23(isLeaf);
splitNodes[0].Parent = Parent;
splitNodes[1].Parent = Parent;
splitNodes[0].AddBookList(RemoveLeftMostBookList());
splitNodes[1].AddBookList(RemoveRightMostBookList());
if(!isLeaf){
Children[0].Parent = splitNodes[0];
Children[1].Parent = splitNodes[0];
splitNodes[0].Children[0] = Children[0];
splitNodes[0].Children[1] = Children[1];
Children[2].Parent = splitNodes[1];
Children[3].Parent = splitNodes[1];
splitNodes[1].Children[0] = Children[2];
splitNodes[1].Children[1] = Children[3];
}
return splitNodes;
}
//Book Functions
public int FirstNullBookList(){
int emptyPos = -1;
for(int i = 0; i < 2; i++){
if(Books[i] == null){
emptyPos = -1;
}
}
return emptyPos;
}
public int GetNextChildByKey(String key){
int nextChild = -1;
if(!isLeaf){
if(size == 1){
if(Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else{
nextChild = 1;
}
}
else{
if(Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else if(Books[1].CompareTo(key) > 0){
nextChild = 1;
}
else{
nextChild = 2;
}
}
}
return nextChild;
}
public int GetMatchingBookListByKey(String key){
int match = -1;
for(int i = 0; i < size; i++){
if(Books[i].CompareTo(key) == 0)
match = i;
}
return match;
}
public void TakeAllBookLists(Node23 n){
for(int i = 0; i < 3; i++){
if(n.Books[i] != null){
AddBookList(n.RemoveBookList(i));
}
}
}
public void ShiftBooksRightFrom(int shiftStart){
for(int i = 2; i > shiftStart; i--){
Books[i] = Books[i - 1];
}
Books[shiftStart] = null;
}
public void ShiftBooksRightInto(int shiftEnd){
for(int i = shiftEnd; i > 0; i--){
Books[i] = Books[i - 1];
}
Books[0] = null;
}
public void ShiftBooksLeftFrom(int shiftStart){
for(int i = 0; i < shiftStart; i++){
Books[i] = Books[i+1];
}
Books[shiftStart] = null;
}
public void ShiftBooksLeftInto(int shiftEnd){
for(int i = shiftEnd; i < 2; i++){
Books[i] = Books[i + 1];
}
Books[2] = null;
}
public void AddBookList(BookList newBookList){
if(size == 0){
Books[0] = newBookList;
}
else{
if(newBookList.CompareTo(Books[0]) < 0){
ShiftBooksRightFrom(0);
Books[0] = newBookList;
}
else{
if(size == 1){
Books[1] = newBookList;
}
else{
if(newBookList.CompareTo(Books[1]) < 0){
ShiftBooksRightFrom(1);
Books[1] = newBookList;
}
else{
Books[2] = newBookList;
}
}
}
}
size++;
}
public void AddBook(Book newBook, String key){
if(size == 0){
AddBookList(new BookList(newBook, key));
}
else{
int match = GetMatchingBookListByKey(key);
if(match != -1){
Books[match].AddBook(newBook);
}
else{
AddBookList(new BookList(newBook, key));
}
}
}
public BookList RemoveRightMostBookList(){
BookList bList = null;
for(int i = 2; i > 0; i--){
if(Books[i] != null){
bList = Books[i];
Books[i] = null;
size--;
break;
}
}
return bList;
}
public BookList RemoveLeftMostBookList(){
BookList bList = null;
bList = Books[0];
ShiftBooksLeftInto(0);
size--;
return bList;
}
public BookList RemoveBookList(int position){
BookList bList = Books[position];
ShiftBooksLeftInto(position);
size--;
return bList;
}
public void RemoveMatchingBook(Book b, String key){
if(Books[0] != null){
if(Books[0].CompareTo(key) == 0){
Books[0].DeleteBooksByISSN(b.ISSN);
}
}
else if(Books[1] != null){
if(Books[1].CompareTo(key) == 0){
Books[1].DeleteBooksByISSN(b.ISSN);
}
}
else if(Books[2] != null){
if(Books[2].CompareTo(key) == 0){
Books[2].DeleteBooksByISSN(b.ISSN);
}
}
}
//Child-Node Functions
public Node23 RemoveLeftMostChild(){
Node23 n = null;
int i = 0;
while(n == null && i <= 3){
if(Children[i] != null){
n = Children[i];
Children[i] = null;
}
i++;
}
return n;
}
public Node23 RemoveRightMostChild(){
Node23 n = null;
int i = 3;
while(n == null && i >= 0 ){
if(Children[i] != null){
n = Children[i];
Children[i] = null;
}
i--;
}
return n;
}
public void AddChildAt(int index, Node23 newChildNode){
Children[index] = newChildNode;
}
public void AddSplitNodeChildAt(int position, Node23[] splitNode){
ShiftChildrenRightFrom(position + 1);
AddChildAt(position, splitNode[0]);
AddChildAt(position + 1, splitNode[1]);
}
public void ShiftChildrenRightFrom(int shiftStart){
for(int i = 3; i > shiftStart; i--){
Children[i] = Children[i - 1];
}
Children[shiftStart] = null;
}
public void ShiftChildrenRightInto(int shiftEnd){
for(int i = shiftEnd; i > 0; i--){
Children[i] = Children[i - 1];
}
Children[0] = null;
}
public void ShiftChildrenLeftFrom(int shiftStart){
for(int i = 0; i < shiftStart; i++){
Children[i] = Children[i + 1];
}
Children[shiftStart] = null;
}
public void ShiftChildrenLeftInto(int shiftEnd){
for(int i = shiftEnd; i < 2; i++){
Children[i] = Children[i + 1];
}
Children[2] = null;
}
//Attribute Functions
public int CountChildren(){
int count = 0;
for(int i = 0; i < 3; i++){
if(Children[i] != null){
count++;
}
}
return count;
}
public boolean IsRoot(){
boolean isRoot = false;
if(Parent == null){
isRoot = true;
}
return isRoot;
}
public int WhichChildAmI(){
int childNum = -1;
if(!IsRoot()){
for(int i = 0; i < Parent.size + 1; i++){
if(Parent.Children[i] == this){
childNum = i;
}
}
}
return childNum;
}
public boolean IsLeaf(){
return isLeaf;
}
public int GetSize(){
return size;
}
}
Class Book: This is the Book class that makes the links of the linked list within each Node23
package bookClasses;
public class Book{
public int ISSN;
public String Title;
public String[] Author;
public Book Next;
public Book(){}
/**
* #param ISSN
* #param Title
* #param Author
*/
public Book(int issn, String title, String author){
ISSN = issn;
Title = title;
Author = author.split(",");
Next = null;
}
private String AuthorToString(){
String author = Author[0];
if(Author.length == 2){
author = author + ", " + Author[1];
}
return author;
}
public void Display(){
System.out.println("\tISSN: " + ISSN);
System.out.println("\tTITLE: " + Title);
System.out.println("\tAUTHOR: " + AuthorToString());
}
public boolean MatchAuthor(String author){
boolean match = false;
if(Author.length == 2){
if(author.compareTo(Author[0].toLowerCase()) == 0
|| author.compareTo(Author[1].toLowerCase()) == 0){
match = true;
}
}
if(author.split(",") == Author){
match = true;
}
return match;
}
}
Class BookList: This is the linked List inside of each node containing copies all books with a matching key
package bookClasses;
public class BookList {
public String Key;
public Book Head;
private int Size;
public BookList(){
Head = null;
Size = 0;
};
public BookList(Book b, String key){
Size = 1;
Key = key;
Head = b;
}
//Insert Functions
public void AddBook(Book newBook){
newBook.Next = Head;
Head = newBook;
Size++;
}
//Search Functions
public BookList GetBooksByISSN(int issn){
BookList books = new BookList();
Book b = Head;
for(int i = 0; i < Size; i++){
if(issn == b.ISSN){
books.AddBook(b);
}
}
return books;
}
public BookList GetBooksByTitle(String title){
BookList matches = new BookList();
Book b = Head;
for(int i = 0; i < Size; i++){
if(title.compareTo(b.Title.toLowerCase()) == 0){
matches.AddBook(b);
}
}
return matches;
}
public BookList GetBooksByAuthor(String author){
BookList books = new BookList();
Book b = Head;
for(int i = 0; i < Size; i++){
if(b.MatchAuthor(author)){
books.AddBook(b);
}
b = b.Next;
}
return books;
}
//Delete Functions
public void DeleteBooksByAuthor(String author){
Book b = Head;
if(b.MatchAuthor(author)){
Head = b.Next;
Size--;
}
else{
while(b.Next != null){
if(b.Next.MatchAuthor(author)){
b.Next = b.Next.Next;
Size--;
}
else{
b = b.Next;
}
}
}
}
public void DeleteBooksByTitle(String title){
Book b = Head;
if(b.Title.toLowerCase().compareTo(title.toLowerCase()) == 0){
Head = b.Next;
Size--;
}
else{
while(b.Next != null){
if(b.Next.Title.toLowerCase().compareTo(title.toLowerCase()) == 0){
b.Next = b.Next.Next;
Size--;
}
else{
b = b.Next;
}
}
}
}
public void DeleteBooksByISSN(int issn){
Book b = Head;
if(b.ISSN == issn){
Head = b.Next;
Size--;
}
else{
while(b.Next != null){
if(b.Next.ISSN == issn){
b.Next = b.Next.Next;
Size--;
}
else{
b = b.Next;
}
}
}
}
//Other Methods
public void Displayall(){
Book b = Head;
for(int i = 0; i < Size; i++){
b.Display();
b = b.Next;
}
}
public int CompareTo(BookList bookList){
return (Key.compareTo(bookList.Key));
}
public int CompareTo(String key){
return (Key.compareTo(key));
}
public int Size(){
return Size;
}
}
Heres the input file - the 1 specifies INSERT
1
60
The Black Dahlia
James,Ellroy
1
98
The Turn of the Screw
Henry,James
1
147
The Wings of the Dove
Henry,James
1
151
A Portrait of the Artist as a Young Man
James,Joyce
1
157
The Postman Always Rings Twice
James,M.
1
184
How Late It Was, How Late
James,Kelman
1
186
A Disaffection
James,Kelman
1
320
The Ambassadors
Henry,James
1
326
What Maisie Knew
Henry,James
1
327
The Golden Bowl The Golden Bowl
Henry,James
1
353
The Charwoman's Daughter
James,Stephens
1
362
Ulysses
James,Joyce
1
478
Finnegans Wake
James,Joyce
After inserting ulysses
The Black Dahlia
The Turn of the Screw
The Wings of the Dove
A Portrait of the Artist as a Young Man
The Postman Always Rings Twice
How Late It Was, How Late
A Disaffection
The Ambassadors
What Maisie Knew
The Golden Bowl The Golden Bowl
The Charwoman's Daughter
Ulysses <==Head
Now here's where it gets wacky:
if I try and insert this entry:
478
Finnegans Wake
James,Joyce
bringing the size of the list from 12, to 13,
the new order of the list becomes:
The Black Dahlia
The Turn of the Screw
The Wings of the Dove
A Portrait of the Artist as a Young Man
The Postman Always Rings Twice
How Late It Was, How Late
A Disaffection
The Ambassadors
What Maisie Knew
The Golden Bowl The Golden Bowl
Ulysses
Finnegans Wake <=======HEAD
The Charwomans daughter has dissappeared.
This change happens when Head = newBook;
So, I thought it might have something to do with my hardware, and the computer I originally had this project stored on uses an AMD processor, so I got on my intel laptop and accessed the AMD desktop over the network. I copied the project file into my workspace on the laptop - Just a simple drag and drop.
First I run the code on the intel laptop,, and as expected, it doesnt work, then I run the code on the desktop again, and NOW IT WORKS. No changes were made.
After the code worked on the desktop, it suddenly worked on the laptop.

NullPointerException even when variables are not null

I'm currently designing a program to simulate an airport. I ran into a problem and I've already tried my best to figure out the problem and posting to this site was my final resort.
It keeps giving me a "Exception in thread "main" java.lang.NullPointerException at AirportApp.main(AirportApp.java:119)" which is under the //Landings section with the code
System.out.println(plane1.getCapacity());
The reason I did the print is to make sure plane1.getCapacity isn't a null. This is because when I tried the code below it
if(plane1.getCapacity() < 300);
it gave me the NullPointerException error. I did the print and it didn't return a null.
What I'm trying to do here is whenever a plane lands, it will be assigned to an empty gate. If the plane has a capacity of 300 or more, it will be assigned to the 4th or 5th gate only. The other planes can be assigned to any gate.
What I noticed was that the error happens only when the capacity is over 300.
I've already looked at my code over and over again making sure all variables were initialized and I still could not find anything wrong. Any help or hints will be greatly appreciated. Apologies for the messy code.
Main class.
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class AirportApp {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
Random rn = new Random();
String [] flightNames = {"SQ", "MI", "TZ", "TR", "EK", "MO", "FC"};
int [] flightNum = {8421, 5361, 6342, 6135, 8424, 7424, 5435};
Queue landingRunway = new Queue(10);
Queue takeoffRunway = new Queue(10);
Queue planesQueue = new Queue(100);
Queue gatesQueue = new Queue(100);
ArrayList<Gate> allGates = new ArrayList();
for(int i = 1 ; i < 6 ; i++)
{
allGates.add(new Gate(i, 0, 0, true));
}
int minutes = 0;
int planesMissedTime = 0;
Boolean highWinds = null;
int tookOffPlanes = 0;
int smallCapPlanes = 0;
int largeCapPlanes = 0;
int landedPlanes = 0;
System.out.println("Please key in the number of minutes you want "
+ "the program to run: ");
int desiredMinutes = sc.nextInt();
while(minutes < desiredMinutes)
{
//Randomise wind warnings
int windRandom = rn.nextInt(2) + 1;
if(windRandom == 1)
{
highWinds = true;
}
if(windRandom == 2)
{
highWinds = false;
}
//Empty the gates
for(Gate c : allGates)
{
if(c.getAvailability() == false)
{
c.addMinInQueue(1);
if(c.getMinInQueue() == 15)
{
c.isAvailable();
}
}
}
//Every 2 minutes
if(minutes % 2 == 0)
{
//Randomise flight names and number
int index = rn.nextInt(flightNames.length);
int index1 = rn.nextInt(flightNum.length);
String name = flightNames[index];
int num = flightNum[index1];
//Randomise plane assignment
int planeDirection = rn.nextInt(2) + 1;
int planeCap = rn.nextInt(401) + 100;
//Arrival Planes
if(planeDirection == 1)
{
planesQueue.enqueue(new Plane(num, name, planeCap, 5 , 0 ));
System.out.println("A plane has been generated.");
}
//Departure Planes
if(planeDirection == 2)
{
planesQueue.enqueue(new Plane(num, name, planeCap, 0 , 5 ));
System.out.println("A plane has been generated.");
}
//Take-Offs
if(!takeoffRunway.isEmpty())
{
System.out.println("A plane has departed.");
Plane departPlane = (Plane) takeoffRunway.dequeue();
if (departPlane.getCapacity() < 300)
{
smallCapPlanes++;
}
tookOffPlanes++;
}
}
//Landings
if(minutes % 3 == 0 && !landingRunway.isEmpty())
{
System.out.println("A plane has landed.");
gatesQueue.enqueue(landingRunway.dequeue());
landedPlanes++;
loop1:
for(Gate e : allGates)
{
if(e.getAvailability() == true)
{
Plane plane1 = (Plane) gatesQueue.dequeue();
System.out.println(plane1.getCapacity());
if(plane1.getCapacity() < 300)
{
e.addNumOfPlanes(1);
e.setAvailability(false);
break loop1;
}
if(plane1.getCapacity() > 300)
{
largeCapPlanes++;
if(e.getGateId() == 4 || e.getGateId() == 5)
{
e.addNumOfPlanes(1);
e.setAvailability(false);
break loop1;
}
}
}
}
}
//Plane assigned to takeoff or landing queue
if(minutes % 5 == 0)
{
Plane item = (Plane) planesQueue.peek();
if(item.getArrivalTime() == 5 && landingRunway.isEmpty()
&& highWinds == false)
{
landingRunway.enqueue(planesQueue.dequeue());
System.out.println("A plane has been assigned to "
+ "the landing queue.");
}
else if(item.getDepartureTime() == 5 &&
takeoffRunway.isEmpty() && highWinds == false)
{
takeoffRunway.enqueue(planesQueue.dequeue());
System.out.println("A plane has been assigned to "
+ "the takeoff queue.");
}
else
{
planesMissedTime++;
}
}
minutes++;
}
Class 1
public class Plane
{
private int flightNo;
private String flightName;
private int capacity;
private int timeOfArrival;
private int timeOfDeparture;
private int delayTime;
public Plane(int flightNo, String flightName, int capacity,
int timeOfArrival, int timeOfDeparture)
{
this.flightNo = flightNo;
this.flightName = flightName;
this.capacity = capacity;
this.timeOfArrival = timeOfArrival;
this.timeOfDeparture = timeOfDeparture;
}
public void setFlightNum(int flightNo)
{
this.flightNo = flightNo;
}
public int getFlightNum()
{
return this.flightNo;
}
public void setFlightName(String flightName)
{
this.flightName = flightName;
}
public String getflightName()
{
return this.flightName;
}
public void addCapacity(int capacity)
{
this.capacity = capacity;
}
public int getCapacity()
{
return this.capacity;
}
public void setArrivalTime(int newArrivalTime)
{
this.timeOfArrival = newArrivalTime;
}
public int getArrivalTime()
{
return this.timeOfArrival;
}
public void setDepartureTime(int newDepartureTime)
{
this.timeOfDeparture = newDepartureTime;
}
public int getDepartureTime()
{
return this.timeOfDeparture;
}
}
Class 2
public class Gate
{
private int gateID;
private int numOfPlanes;
private int minInQueue;
private boolean availability;
public Gate(int id, int numPlanes, int minQueue, boolean available)
{
this.gateID = id;
this.numOfPlanes = numPlanes;
this.minInQueue = minQueue;
this.availability = available;
}
public int getGateId()
{
return this.gateID;
}
public void setGateId(int newID)
{
this.gateID = newID;
}
public int getNumOfPlanes()
{
return this.numOfPlanes;
}
public void addNumOfPlanes(int addNum)
{
this.numOfPlanes += addNum;
}
public int getMinInQueue()
{
return this.minInQueue;
}
public void setMinInQueue(int setMin)
{
this.minInQueue = 0;
}
public void addMinInQueue(int addMin)
{
this.minInQueue += addMin;
}
public boolean getAvailability()
{
return this.availability;
}
public void setAvailability(Boolean setAvailability)
{
this.availability = setAvailability;
}
public void isAvailable()
{
this.availability = true;
this.minInQueue = 0;
}
}
Queue class
class Queue
{
private int count;
private int front = 0;
private int rear = 0;
private Object [] items;
public Queue(int maxSize)
{
count = 0;
front = -1;
rear = -1;
items = new Object [maxSize];
}
public boolean enqueue (Object x)
{
if (count == items.length)
{
return false;
}
else
{
rear = (rear + 1) % items.length;
items[rear] = x;
if (count == 0)
{
front = 0;
}
count++;
return true;
}
}
public Object dequeue()
{
if (count == 0)
{
return null;
}
else
{
Object result = items[front];
front = (front + 1) % items.length;
count--;
if (count == 0)
{
front = -1;
rear = -1;
}
return result;
}
}
public int size()
{
return count;
}
public boolean isEmpty()
{
if (count == 0)
{
return true;
}
else
{
return false;
}
}
public Object peek()
{
if (count == 0)
{
return null;
}
else
{
return items[front];
}
}
}
The problem lies in the second if statement
if (plane1.getCapacity() > 300) {
largeCapPlanes++;
if (e.getGateId() == 4 || e.getGateId() == 5) {
e.addNumOfPlanes(1);
e.setAvailability(false);
break loop1;
}
}
You only break your loop if the gate is 4, or 5. So, if it is not gate 4 or 5, then you code will loop back to the next gate, grab another plane from the queue (which is empty and your plane1 is now null) and then try to get the capacity. And there you get your null pointer.
Note: Be careful nesting loops and if statements. This is where bugs enjoy living.
Happy Coding!
I ran the code and didn't get an error until I tried a large number for the time (1000). I'm assuming the error is with the Plane plane1 = (Plane) gatesQueue.dequeue(); section. I would throw some debug statements in there to see if for large n that the Queue is generated properly. if dequeue() returns null then plane1 will also be null
EDIT:
So I debugged it and confirmed that the issue is with your plane object in that loop. You enqueue your gates: gatesQueue.enqueue(landingRunway.dequeue()); then you run a loop: for(Gate e : allGates) and then you dequeue: Plane plane1 = (Plane) gatesQueue.dequeue();
If you dequeue more than what you enqueue you will return null. So you'll either have to change how you do your queue or put a check in that for-loop to check the size of your queue.
The reason you are seeing a number when you do your System.out.println() is because it is displaying that, returning to the top of the loop, and then trying to get the plane object again before you run the print again.

Want to add a element in desired index. But adding last

I use add method to add an element to a desired index. But it is adding last. I want to add an element to a desired index. How can do it with this. Is is possible? without end pointer.
import java.util.*;
class List {
Customer listPtr;
int index;
public void add(Customer customer) {
Customer temp = customer;
if (listPtr == null) {
listPtr = temp;
index++;
} else {
Customer x = listPtr;
while (x.next != null) {
x = x.next;
}
x.next = temp;
index++;
}
}
public void add(int index, Customer customer) {
int size = size();
while (size != -1) {
size--;
if (size == index) {
System.out.println(size + ":" + index);
add(customer);
}
}
}
public void removeFirst() {
Customer temp = listPtr;
if (listPtr != null) {
listPtr = temp.next;
}
}
public void removeLast() {
Customer temp = listPtr;
while (temp.next.next != null) {
temp = temp.next;
}
temp.next = null;
index--;
}
public void removeAll() {
Customer temp = listPtr;
while (temp != null) {
listPtr = temp.next;
temp = temp.next;
}
}
public int size() {
int size = 0;
Customer temp = listPtr;
while (temp != null) {
size++;
temp = temp.next;
}
return size;
}
public void printList() {
Customer temp = listPtr;
while (temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
}
class DemoList {
public static void main(String args[]) {
List list = new List();
Customer c1 = new Customer("10011", "Sam");
Customer c2 = new Customer("10012", "Jason");
Customer c3 = new Customer("10013", "Arnold");
Customer c4 = new Customer("10014", "Bob");
Customer c5 = new Customer("10015", "Tom");
list.add(c1);
list.add(c2);
list.add(c3);
list.add(c4);
list.add(2, c5);
System.out.println(list.size());
list.printList();
}
}
class Customer {
String id;
String name;
Customer next;
public Customer(String id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return id + " : " + name;
}
public boolean equals(Object ob) {
Customer c = (Customer) ob;
return this.id.equals(c.id);
}
}
Try this, finds index from the beginning and adds customer at that position
public void add(int index, Customer customer) {
int size = size();
Customer tmp=listPtr,tmp2;
int i=0;
//some boundary cases
if((index<0) ||(index>size)){
return;
}
//assumes all other cases are handled
while (i != size) {
if ((i+1) == index) {
System.out.println(size + ":" + index);
tmp2=tmp.next;
tmp.next=customer;
customer.next=tmp2;
break;
}
tmp=tmp.next;
++i;
}
}
Suppose you have two Customers, a, and b, and they are hooked up together.
Customer a = new Customer("a", "John");
Customer b = new Customer("b", "George");
a.next = b;
Now, you want to slip c between them:
Customer c = new Customer("c", "Paul");
You want eventually to have a.next == c and c.next == b. But if you make those changes in the wrong order, your list will have b detached from the rest of the list, and it will be garbage collected. So, do things in the correct order so nothing is lost:
c.next = b; // Now, both a.next and c.next == b.
a.next = c; // Finishing the splice. Now, a.next == c and c.next == b.
To insert items into the list, advance from the beginningindex places.
Customer nth(int n) {
Customer cust = listPtr;
for (int i = 0; i < n; ++i) {
cust = cust.next; // can lead to an NPE; you add the error checking.
}
return cust;
}
Now, get the nth customer, and splice a new one in. Again, watch out for NPEs.

Java library or code to parse Newick format?

Anyone knows a good Java library I can use to parse a Newick file easily? Or if you have some tested source code I could use?
I want to read the newick file: http://en.wikipedia.org/wiki/Newick_format in java and generate a visual representation of the same. I have seen some java programs that do that but not easy to find how the parsing works in code.
Check out jebl (Java Evolutionary Biology Library) of FigTree and BEAST fame. Probably a lot more tree functionality than you might need, but it's a solid library.
Stumbled on this question while looking for a Java Newick parser.
I've also come across libnewicktree, which appears to be an updated version of the Newick parser from Juxtaposer.
I like to use the Archaeopteryx library based on the forester libraries. It can do a lot more than parsing and visualizing trees but its usage remains very simple even for basic tasks:
import java.io.IOException;
import org.forester.archaeopteryx.Archaeopteryx;
import org.forester.phylogeny.Phylogeny;
public class PhylogenyTree {
public static void main(String[] args) throws IOException{
String nhx = "(mammal,(turtle,rayfinfish,(frog,salamander)))";
Phylogeny ph = Phylogeny.createInstanceFromNhxString(nhx);
Archaeopteryx.createApplication(ph);
}
}
Here is a Newick parser I wrote for personal use. Use it in good health; there is no visualization included.
import java.util.ArrayList;
/**
* Created on 12/18/16
*
* #author #author Adam Knapp
* #version 0.1
*/
public class NewickTree {
private static int node_uuid = 0;
ArrayList<Node> nodeList = new ArrayList<>();
private Node root;
static NewickTree readNewickFormat(String newick) {
return new NewickTree().innerReadNewickFormat(newick);
}
private static String[] split(String s) {
ArrayList<Integer> splitIndices = new ArrayList<>();
int rightParenCount = 0;
int leftParenCount = 0;
for (int i = 0; i < s.length(); i++) {
switch (s.charAt(i)) {
case '(':
leftParenCount++;
break;
case ')':
rightParenCount++;
break;
case ',':
if (leftParenCount == rightParenCount) splitIndices.add(i);
break;
}
}
int numSplits = splitIndices.size() + 1;
String[] splits = new String[numSplits];
if (numSplits == 1) {
splits[0] = s;
} else {
splits[0] = s.substring(0, splitIndices.get(0));
for (int i = 1; i < splitIndices.size(); i++) {
splits[i] = s.substring(splitIndices.get(i - 1) + 1, splitIndices.get(i));
}
splits[numSplits - 1] = s.substring(splitIndices.get(splitIndices.size() - 1) + 1);
}
return splits;
}
private NewickTree innerReadNewickFormat(String newick) {
// single branch = subtree (?)
this.root = readSubtree(newick.substring(0, newick.length() - 1));
return this;
}
private Node readSubtree(String s) {
int leftParen = s.indexOf('(');
int rightParen = s.lastIndexOf(')');
if (leftParen != -1 && rightParen != -1) {
String name = s.substring(rightParen + 1);
String[] childrenString = split(s.substring(leftParen + 1, rightParen));
Node node = new Node(name);
node.children = new ArrayList<>();
for (String sub : childrenString) {
Node child = readSubtree(sub);
node.children.add(child);
child.parent = node;
}
nodeList.add(node);
return node;
} else if (leftParen == rightParen) {
Node node = new Node(s);
nodeList.add(node);
return node;
} else throw new RuntimeException("unbalanced ()'s");
}
static class Node {
final String name;
final int weight;
boolean realName = false;
ArrayList<Node> children;
Node parent;
/**
* #param name name in "actualName:weight" format, weight defaults to zero if colon absent
*/
Node(String name) {
int colonIndex = name.indexOf(':');
String actualNameText;
if (colonIndex == -1) {
actualNameText = name;
weight = 0;
} else {
actualNameText = name.substring(0, colonIndex);
weight = Integer.parseInt(name.substring(colonIndex + 1, name.length()));
}
if (actualNameText.equals("")) {
this.realName = false;
this.name = Integer.toString(node_uuid);
node_uuid++;
} else {
this.realName = true;
this.name = actualNameText;
}
}
#Override
public int hashCode() {
return name.hashCode();
}
#Override
public boolean equals(Object o) {
if (!(o instanceof Node)) return false;
Node other = (Node) o;
return this.name.equals(other.name);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
if (children != null && children.size() > 0) {
sb.append("(");
for (int i = 0; i < children.size() - 1; i++) {
sb.append(children.get(i).toString());
sb.append(",");
}
sb.append(children.get(children.size() - 1).toString());
sb.append(")");
}
if (name != null) sb.append(this.getName());
return sb.toString();
}
String getName() {
if (realName)
return name;
else
return "";
}
}
#Override
public String toString() {
return root.toString() + ";";
}
}
Seems like Tree Juxtaposer includes a newick tree parser (however limited to only one tree per file).

Categories