File reading error with postfix calculator - java

I made a postfix calculator and I'm pretty sure it works however it as a reading error. The calculator is designed to read numbers in postfix notation from a line in a file and calc them. However it doesn't recognize lines, for example if I have two lines it will combine the two expressions. I have trouble with file reading so any help would be appreciated. Sorry for any format problem this is my first post. So here is my code so my issue is better understood.
import java.io.*;
import java.util.*;
import java.nio.charset.Charset;
public class PostfixCalculator {
private static final String ADD = "+";
private static final String SUB = "-";
private static final String MUL = "*";
private static final String DIV = "/";
private static final String EXP = "^";
private static final String NEG = "_"; //unary negation
private static final String SQRT = "#";
public void calculateFile(String fileName) throws IOException {
BufferedReader br = null;
StringBuilder sb = null;
try {
FileReader fileReader = new FileReader(fileName);
br = new BufferedReader(fileReader);
sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
String input = sb.toString();
System.out.println(input + " = " + calculate(input));
} catch (IOException e) {
e.printStackTrace();
} finally {
br.close();
}
}
private double calculate(String input) {
SinglyLinkedListStack<Double> stack = new SinglyLinkedListStack<Double>();
String[] inputs = input.split(" ");
return handleCalculation(stack, inputs);
}
private static double handleCalculation(SinglyLinkedListStack<Double> stack, String[] el) {
double operand1, operand2;
for(int i = 0; i < el.length; i++) {
if( el[i].equals(ADD) || el[i].equals(SUB) || el[i].equals(MUL) || el[i].equals(DIV)||el[i].equals(EXP)||el[i].equals(NEG)||el[i].equals(SQRT)) {
operand2 = stack.pop();
operand1 = stack.pop();
switch(el[i]) {
case ADD: {
double local = operand1 + operand2;
stack.push(local);
break;
}
case SUB: {
double local = operand1 - operand2;
stack.push(local);
break;
}
case MUL: {
double local = operand1 * operand2;
stack.push(local);
break;
}
case DIV: {
double local = operand1 / operand2;
stack.push(local);
break;
}
case EXP: {
double local = Math.pow(operand1, operand2);
stack.push(local);
break;
}
case NEG: {
double local = -(operand1);
stack.push(local);
break;
}
case SQRT:{
double local = Math.pow(operand1, .5);
stack.push(local);
break;
}
}
} else {
stack.push(Double.parseDouble(el[i]));
}
}
return (double)stack.pop();
}
}
This is my linked list
public class SinglyLinkedListStack<T> {
private int size;
private Node<T> head;
public SinglyLinkedListStack() {
head = null;
size = 0;
}
public void push(double local) {
if(head == null) {
head = new Node(local);
} else {
Node<T> newNode = new Node(local);
newNode.next = head;
head = newNode;
}
size++;
}
public T pop() {
if(head == null)
return null;
else {
T topData = head.data;
head = head.next;
size--;
return topData;
}
}
public T top() {
if(head != null)
return head.data;
else
return null;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private class Node<T> {
private T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
}
}
This is my demo
import java.io.IOException;
public class PostFixCalculatorDemo {
public static void main(String[] args) throws IOException {
PostfixCalculator calc = new PostfixCalculator();
calc.calculateFile("in.dat");
}
}
The text file contains
2 3 ^ 35 5 / -
1 2 + 3 * # 4 - 5 6 - + _
my output is 2 3 ^ 35 5 / -1 2 + 3 * # 4 - 5 6 - + _ = -8.0
as it is seen it is combining the two lines. I want it to read the two lines separately and calculate 2 3 ^ 35 5 / - and 1 2 + 3 * # 4 - 5 6 - + _ without putting it together. I know it does this because I programmed the calculateFile class wrong but I am not sure how to fix this without breaking my program.

while (line != null) {
sb.append(line);
line = br.readLine();
}
Basically you are reading every line and appending it to a single Stringbuffer which will result in concatenation of every line from your file. This buffer wont contain newline character or any other sign where your lines end.
From the documentation:
readline:
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns: A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached Throws:
I advice adding the lines to an ArrayList if you are planning to read everything at once.

Related

How to do different traversals of an expression tree?

I'm trying to figure out how to do the different traversals through an expression tree. For example, if I type in " - + 10 * 2 8 3 ", I want it to print out the prefix, postfix, and infix versions of that expression.
I also need to calculate the result of the expression through a postorder traversal, which should be the evaluate function.
However, when I run my program, I only get the first character of each expression. Is my understanding of how these traversals work wrong?
EDIT: Following suggestions, I saved the result of the buildtree and also changed sc.next to sc.nextLine.
Also, every method should be recursive.
Given "- + 10 * 2 8 3", the expected answer would be:
prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
( ( 10 + ( 2 * 8 ) ) - 3 )
Result = 23
I understand I haven't implemented anything with parentheses for the infix expression, but that's okay for now.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter a prefix expression: ");
Node root = buildTree(sc);
System.out.println("prefix expression: ");
infix(root);
System.out.println("postfix expression: ");
postfix(root);
System.out.println("infix expression: ");
infix(root);
System.out.print("Result = ");
evaluate(root);
}
static Node buildTree(Scanner sc) {
Node n = new Node(null);
int i = 0;
String prefixExpression = sc.nextLine();
String[] temp = prefixExpression.split(" ");
if(n.isLeaf()) {
n.value = temp[i];
n.left = null;
n.right = null;
i++;
}
return n;
}
static void infix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
infix(node.left);
System.out.println(node.value + " ");
infix(node.right);
}
}
void prefix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
switch(node.value) {
case "+":
System.out.print("+");
break;
case "-":
System.out.print("-");
break;
case "*":
System.out.print("*");
break;
case "/":
System.out.print("/");
break;
}
}
prefix(node.left);
System.out.print(" ");
prefix(node.right);
}
static void postfix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
postfix(node.left);
postfix(node.right);
switch (node.value) {
case "+":
System.out.print("+");
break;
case "-":
System.out.print("-");
break;
case "*":
System.out.print("*");
break;
case "/":
System.out.print("/");
break;
}
}
}
public static int evaluate(Node node) {
if(node.isLeaf()) {
return Integer.parseInt(node.value);
}
else {
int leftHandSide = evaluate(node.getLeft());
int rightHandSide = evaluate(node.getRight());
String operator = node.getValue();
if("+".equals(operator)) {
return leftHandSide + rightHandSide;
}
else if("-".equals(operator)) {
return leftHandSide - rightHandSide;
}
else if("*".equals(operator)) {
return leftHandSide * rightHandSide;
}
else if("/".equals(operator)) {
return leftHandSide / rightHandSide;
}
else {
System.out.println("Unexpected problem. Error.");
}
return 0;
}
}
}
Here is Node.java, There's getters and setters too.
public class Node<E> {
String value;
Node<E> left;
Node<E> right;
Node(String value){
left = null;
right = null;
this.value = value;
}
Node(String value, Node<E> left, Node<E> right) {
this.value = value;
this.left = left;
this.right = right;
}
boolean isLeaf() {
return (left == null && right == null);
}
EDIT:
Since your question says "How to do different traversals of an expression tree?, The problem I can see in your code is building the tree ( i.e. buildTree() method).
In order to correct this, I have used buildExpressionTree(array) method to convert your prefix input to an expression tree using Stack data structure.
Construction of Expression Tree:
For constructing expression tree I have use a stack. Since in your case input is in prefix form so Loop in reverse through input expression and do following for every character.
If character is operand push that into stack
If character is operator pop two values from stack make them its
child and push current node again.
At the end only element of stack will be root of expression tree.
Also while printing different traversals, you do not need all those if conditions to check for different operators.You can simply do the traversal as shown in my code below.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a prefix expression: ");
String prefixExpression = sc.nextLine();
String[] temp = prefixExpression.split(" ");
Node n = null;
n = buildExpressionTree(temp);
System.out.println("prefix expression: ");
prefix(n);
System.out.println();
System.out.println("postfix expression: ");
postfix(n);
System.out.println();
System.out.println("infix expression: ");
infix(n);
System.out.println();
int result = evaluate(n);
System.out.print("Result = "+ result);
}
static Node buildExpressionTree(String[] input) {
Stack<Node> st = new Stack();
Node t, t1, t2;
// Traverse through every character of
// input expression
for (int i = (input.length-1); i >= 0; i--) {
// If operand, simply push into stack
if (isNumber(input[i])) {
t = new Node(input[i]);
st.push(t);
} else // operator
{
t = new Node(input[i]);
// Pop two top nodes
// Store top
t1 = st.pop(); // Remove top
t2 = st.pop();
// make them children
t.left = t1;
t.right = t2;
st.push(t);
}
}
t = st.peek();
st.pop();
return t;
}
static boolean isNumber(String s) {
boolean numeric = true;
try {
Integer num = Integer.parseInt(s);
} catch (NumberFormatException e) {
numeric = false;
}
return numeric;
}
static void infix(Node node) {
if( null == node) {
return;
}
infix(node.left);
System.out.print(node.value + " ");
infix(node.right);
}
static void prefix(Node node) {
if( null == node) {
return;
}
System.out.print(node.value+ " ");
prefix(node.left);
prefix(node.right);
}
static void postfix(Node node) {
if( null == node) {
return;
}
postfix(node.left);
postfix(node.right);
System.out.print(node.value+ " ");
}
public static int evaluate(Node node) {
if(node.isLeaf()) {
return Integer.parseInt(node.value);
}
else {
int leftHandSide = evaluate(node.left);
int rightHandSide = evaluate(node.right);
String operator = node.value;
if("+".equals(operator)) {
return leftHandSide + rightHandSide;
}
else if("-".equals(operator)) {
return leftHandSide - rightHandSide;
}
else if("*".equals(operator)) {
return leftHandSide * rightHandSide;
}
else if("/".equals(operator)) {
return leftHandSide / rightHandSide;
}
else {
System.out.println("Unexpected problem. Error.");
}
return 0;
}
}
OUTPUT:
Enter a prefix expression:
- + 10 * 2 8 3
prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
10 + 2 * 8 - 3
Result = 23

Java Stack Evaluation from TXT file

In this assignment, I need to read a .txt file and determine if the expressions are correct or "Balanced". The first problem I got correct but for the second problem I am getting more output than I want. Here is the problem for #2:
Write a stack-based algorithm that evaluates a post-fixed expression. Your program needs to read its input from a file called “problem2.txt”. This file contains one expression per line.
For each expression output its value to the standard output. If an expression is ill-formed print “Ill-formed”.
The Problem2.txt is as follows:
3 2 + 5 6 8 2 / + + * 1 +
8 * 2 3 + + - 9 1 +
1 4 + 9 4 - * 2 *
// For my output I need to get:
76
Ill-formed
50
// With my code I am getting:
76
Ill-formatted
Ill-formatted
Ill-formatted
10
50
// and I’m not sure why I’m getting extra ill-formatted and a 10 in there
Below is my code:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Stack;
import java.util.EmptyStackException;
public class Eval {
public static void main(String args[]) throws IOException {
//driver
try (BufferedReader filereader = new BufferedReader(new FileReader("Problem1.txt"))) {
while (true) {
String line = filereader.readLine();
if (line == null) {
break;
}
System.out.println(balancedP(line));
}
}
System.out.println("\n");
try (BufferedReader filereader2 = new BufferedReader(new FileReader("Problem2.txt"))) {
while (true) {
String line = filereader2.readLine();
if (line == null) {
break;
}
System.out.println(evaluatePostfix(line));
}
}
}
public static boolean balancedP (String s) {
Stack<Character> stackEval = new Stack<Character>();
for(int i = 0; i < s.length(); i++) {
char token = s.charAt(i);
if(token == '[' || token == '(' || token == '{' ) {
stackEval.push(token);
} else if(token == ']') {
if(stackEval.isEmpty() || stackEval.pop() != '[') {
return false;
}
} else if(token == ')') {
if(stackEval.isEmpty() || stackEval.pop() != '(') {
return false;
}
} else if(token == '}') {
if(stackEval.isEmpty() || stackEval.pop() != '{') {
return false;
}
}
}
return stackEval.isEmpty();
}
//problem 2 algo to evaluate a post-fixed expression
static int evaluatePostfix(String exp) throws EmptyStackException
{
Stack<Integer> stackEval2 = new Stack<>();
for(int i = 0; i < exp.length(); i++)
{
char c = exp.charAt(i);
if(c == ' ')
continue;
else if(Character.isDigit(c)) {
int n = 0;
while(Character.isDigit(c)) {
n = n*10 + (int)(c-'0');
i++;
c = exp.charAt(i);
}
i--;
stackEval2.push(n);
}
else {
try {
//if operand pops two values to do the calculation through the switch statement
int val1 = stackEval2.pop();
int val2 = stackEval2.pop();
//operands in a switch to test and do the operator's function each value grabbed and tested
switch(c) {
case '+':
stackEval2.push(val2 + val1);
break;
case '-':
stackEval2.push(val2 - val1);
break;
case '/':
stackEval2.push(val2 / val1);
break;
case '*':
stackEval2.push(val2 * val1);
break;
}
} catch (EmptyStackException e) {
System.out.println("Ill-formatted");
}
}
}
return stackEval2.pop();
}
}
A simple way to have the output formatted how you want is to just put the try-catch block around where you are calling the evaluatePostfix() method (make sure to delete the try-catch block that is inside the evaluatePostfix() method):
System.out.println("\n");
try (BufferedReader filereader2 = new BufferedReader(new FileReader("Problem2.txt"))) {
while (true) {
String line = filereader2.readLine();
if (line == null) {
break;
}
try {
System.out.println(evaluatePostfix(line));
} catch (EmptyStackException e) {
System.out.println("Ill-formatted");
}
}
}
This way, when an exception occurs inside the evaluatePostfix() method, the method will throw the exception and the exception will be dealt with outside of the looping, thus, avoiding duplicate error messages and other unwanted effects.

Expression tree won't work properly with numbers bigger than 9

I am finishing up an expression tree program that takes in a postfix and gives the answer and the orginal equation back in infix form. I started working on about 6 months ago and had an issue I couldn't figure out. It works fine if the numbers are smaller than 9. For instance, 2 5 * 4 - prints out The infix: (2*5-4) 6.0 works fine. Something like 10 2 * prints out 20.0 but prints out The infix: (0*2) which isn't right. The big problem is that if a number is bigger than 9 it doesn't read that number in properly which messes up the conversion to infix. I am not sure how to fix this problem exactly. Below is my class and tester class:
import java.util.NoSuchElementException;
import java.util.Stack;
public class ExpressionTree
{
private final String postfix;
private TreeNode root;
/**
* Takes in a valid postfix expression and its used to construct the expression tree.
*/
public ExpressionTree(String postfix)
{
if (postfix == null) { throw new NullPointerException("The posfix should not be null"); }
if (postfix.length() == 0) { throw new IllegalArgumentException("The postfix should not be empty"); }
this.postfix = postfix;
}
private static class TreeNode
{
TreeNode left;
char ch;
TreeNode right;
TreeNode(TreeNode left, char ch, TreeNode right) {
this.left = left;
this.ch = ch;
this.right = right;
}
}
/**
* Checks to see if it is an Operator
*/
private boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
/**
* Constructs an expression tree, using the postfix expression
*/
public void createExpressionTree()
{
final Stack<TreeNode> nodes = new Stack<TreeNode>();
for (int i = 0; i < postfix.length(); i++)
{
char ch = postfix.charAt(i);
if (isOperator(ch))
{
TreeNode rightNode = nodes.pop();
TreeNode leftNode = nodes.pop();
nodes.push(new TreeNode(leftNode, ch, rightNode));
}
else if (!Character.isWhitespace(ch))
{
nodes.add(new TreeNode(null, ch, null));
}
}
root = nodes.pop();
}
/**
* Returns the infix expression
*
* #return the string of infix.
*/
public String infix()
{
if (root == null)
{
throw new NoSuchElementException("The root is empty, the tree has not yet been constructed.");
}
final StringBuilder infix = new StringBuilder();
inOrder(root, infix);
return infix.toString();
}
private void inOrder(TreeNode node, StringBuilder infix)
{
if (node != null) {
inOrder(node.left, infix);
infix.append(node.ch);
inOrder(node.right, infix);
}
}
public Double evaluate(String postfix)
{
Stack<Double> s = new Stack<Double>();
char[] chars = postfix.toCharArray();
int N = chars.length;
for(int i = 0; i < N; i++)
{
char ch = chars[i];
if(isOperator(ch))
{
switch(ch)
{
case '+': s.push(s.pop() + s.pop()); break;
case '*': s.push(s.pop() * s.pop()); break;
case '-': s.push(-s.pop() + s.pop()); break;
case '/': s.push(1 / s.pop() * s.pop()); break;
}
}
else if(Character.isDigit(ch))
{
s.push(0.0);
while (Character.isDigit(chars[i]))
s.push(10.0 * s.pop() + (chars[i++] - '0'));
}
}
return s.pop();
}
}
And the tester:
import java.util.Scanner;
public class ExpressionTester
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String line = null;
while(true)
{
System.out.println("");
String pf = sc.nextLine();
if (pf.isEmpty())
{
break;
}
ExpressionTree eT = new ExpressionTree(pf);
eT.createExpressionTree();
System.out.println("The infix: " + "(" + eT.infix() + ")" );
System.out.println(eT.evaluate(pf));
}
}
}

Trie: insert method - differ between two cases

I am trying to implement an insert method of the Paricia trie data structure. I handled many cases but currently I am stuck in the case to differ these both cases:
case 1: Inserting the following 3 strings:
abaxyxlmn, abaxyz, aba
I could implement this case with the code below.
case 2: Inserting the following 3 strings:
abafg, abara, a
In the second case I do not know how to differ between the first and the second case since I need a clue to know when should I append the different substring ab to the childern edge to get abfa, abra. Finally, add ab as a child too to the node a. Please see the image below.
Code:
package patriciaTrie;
import java.util.ArrayList;
import java.util.Scanner;
public class Patricia {
private TrieNode nodeRoot;
private TrieNode nodeFirst;
// create a new node
public Patricia() {
nodeRoot = null;
}
// inserts a string into the trie
public void insert(String s) {
if (nodeRoot == null) {
nodeRoot = new TrieNode();
nodeFirst = new TrieNode(s);
nodeFirst.isWord = true;
nodeRoot.next.add(nodeFirst);
} else {
// nodeRoot.isWrod = false;
insert(nodeRoot, s);
}
}
private String checkEdgeString(ArrayList<TrieNode> history, String s) {
StringBuilder sb = new StringBuilder();
for (TrieNode nextNodeEdge : history) {
int len1 = nextNodeEdge.edge.length();
int len2 = s.length();
int len = Math.min(len1, len2);
for (int index = 0; index < len; index++) {
if (s.charAt(index) != nextNodeEdge.edge.charAt(index)) {
break;
} else {
char c = s.charAt(index);
sb.append(c);
}
}
}
return sb.toString();
}
private void insert(TrieNode node, String s) {
ArrayList<TrieNode> history = new ArrayList<TrieNode>();
for (TrieNode nextNodeEdge : node.getNext()) {
history.add(nextNodeEdge);
}
String communsubString = checkEdgeString(history, s);
System.out.println("commun String: " + communsubString);
if (!communsubString.isEmpty()) {
for (TrieNode nextNode : node.getNext()) {
if (nextNode.edge.startsWith(communsubString)) {
String substringSplit1 = nextNode.edge
.substring(communsubString.length());
String substringSplit2 = s.substring(communsubString
.length());
if (substringSplit1.isEmpty() && !substringSplit2.isEmpty()) {
// 1. case: aba, abaxyz
} else if (substringSplit2.isEmpty()
&& !substringSplit1.isEmpty()) {
// 2. case: abaxyz, aba
ArrayList<TrieNode> cacheNextNode = new ArrayList<TrieNode>();
System.out.println("node edge string is longer.");
if (nextNode.getNext() != null && !nextNode.getNext().isEmpty()) {
for (TrieNode subword : nextNode.getNext()) {
subword.edge = substringSplit1.concat(subword.edge); //This line
cacheNextNode.add(subword);
}
nextNode.getNext().clear();
nextNode.edge = communsubString;
nextNode.isWord = true;
TrieNode child = new TrieNode(substringSplit1);
child.isWord = true;
nextNode.next.add(child);
for(TrieNode node1 : cacheNextNode){
child.next.add(node1);
System.out.println("Test one");
}
cacheNextNode.clear();
}else{
nextNode.edge = communsubString;
TrieNode child = new TrieNode(substringSplit1);
child.isWord = true;
nextNode.next.add(child);
System.out.println("TEST");
}
} else if(substringSplit1.isEmpty() && substringSplit2.isEmpty()){
//3. case: aba and aba.
nextNode.isWord = true;
}else {
// 4. Case: abauwt and abaxyz
//if(nextNode.getNext().isEmpty())
}
break;
}
}
} else {
// There is no commun substring.
System.out.println("There is no commun substring");
TrieNode child = new TrieNode(s);
child.isWord = true;
node.next.add(child);
}
}
public static void main(String[] args) {
Patricia p = new Patricia();
Scanner s = new Scanner(System.in);
while (s.hasNext()) {
String op = s.next();
if (op.equals("INSERT")) {
p.insert(s.next());
}
}
}
class TrieNode {
ArrayList<TrieNode> next = new ArrayList<TrieNode>();
String edge;
boolean isWord;
// To create normal node.
TrieNode(String edge) {
this.edge = edge;
}
// To create the root node.
TrieNode() {
this.edge = "";
}
public ArrayList<TrieNode> getNext() {
return next;
}
public String getEdge() {
return edge;
}
}
}

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