diff --git a/src/biotree/BioTree.java b/src/biotree/BioTree.java index 2af55698db3142780c55e2f3d8e126a18ee9e7ae..891480d81191ac7c9eb675ee92ef3ab4f84b3ce2 100644 --- a/src/biotree/BioTree.java +++ b/src/biotree/BioTree.java @@ -1,14 +1,18 @@ package biotree; +import java.io.IOException; + +import search.BST; + public class BioTree { - private static Species[] species; + private static BST<Integer, TaxonNode> nodes; private static int n; /** * Initialize species abstract object */ public static void init() { - species = new Species[500]; + nodes = new BST<Integer, TaxonNode>(); n = 0; } @@ -33,27 +37,48 @@ public class BioTree { } /** - * Add a new species to the module + * Process a record. Adds classification to tree if it doesn't exist. + * Returns the taxonId of the new / existing record. * - * @param s - * New Species to add. - * @return speciesid of new species entry + * @param taxonId The taxonId of the possible new entry + * @return taxonId of new species entry */ - public static int addSpecies(Species s) { - species[n++] = s; - return n; + public static int processRecord(int taxonId) { + processTaxonId(taxonId); + return taxonId; } - + /** - * Update an existing species object. + * Process a record. Adds classification to tree if it doesn't exist. + * Returns the taxonId of the new / existing record. * - * @param i - * The index of the species to update. - * @param s - * The new Species object to overwrite the old one with. + * @param scientificName The scientific name of the possible new entry + * @return taxonId of new / existing entry + * @throws IOException + */ + public static int processRecord(String scientificName) throws IOException { + int taxonId = WormsAPI.nameToID(scientificName); + processTaxonId(taxonId); + return taxonId; + } + + /** + * Process a new entry if it doesn't exist. + * @param taxonId */ - public static void setSpecies(int i, Species s) { - species[i] = s; + private static void processTaxonId(int taxonId) { + TaxonNode[] newNodes = WormsAPI.idToClassification(taxonId); + for (int i = newNodes.length - 1; i > 0; i--) { + TaxonNode tx = newNodes[i]; + TaxonNode result = nodes.get(tx.getTaxonId()); + TaxonNode parent = nodes.get(newNodes[i - 1].getTaxonId()); + if (parent == null) parent = newNodes[i - 1]; + if (result == null) { //if node is not found, add it + tx.setParent(parent); + parent.addChild(tx); + } else + break; //stop loop if this node already exists in the tree + } } /** @@ -63,58 +88,7 @@ public class BioTree { * The speciesid (index) of the species. * @return The Species object. */ - public static Species getSpecies(int i) { - return species[i]; + public static TaxonNode getTaxonRecord(int taxonId) { + return nodes.get(taxonId); } - - /** - * Search for a species by name. - * - * @param s - * The name of the species. - * @return The speciesid of the species or -1 if it is not found. - */ - public static int findSpecies(String s) { - for (int i = 0; i < n; i++) - if (species[i].getSpecies() == s) - return i; - return -1; - } - - /** - * TODO: Implement - * - * @param s - * The name of the genus. - * @return Array of speciesid belonging to the genus. - */ - public static int[] findGenus(String s) { - int[] dummy = { 1, 2, 3 }; - return dummy; - } - - /** - * TODO: Implement - * - * @param s - * The name of the family. - * @return Array of speciesid belonging to the family. - */ - public static int[] findFamily(String s) { - int[] dummy = { 1, 2, 3 }; - return dummy; - } - - /** - * TODO: Implement - * - * @param s - * The name of the order. - * @return Array of speciesid belonging to the order. - */ - public static int[] findOrder(String s) { - int[] dummy = { 1, 2, 3 }; - return dummy; - } - } diff --git a/src/biotree/TestBioTree.java b/src/biotree/TestBioTree.java index 3dfe00455c1187808e2cfb1a07b423f0492539a0..b771b0ecd113e4147654c98cc4002ab6f6a8ab34 100644 --- a/src/biotree/TestBioTree.java +++ b/src/biotree/TestBioTree.java @@ -24,8 +24,8 @@ public class TestBioTree { @Test public void testGetSpecies() { - assert BioTree.getSpecies(0).getSpecies() == "Morone chrysops"; - assert BioTree.getSpecies(1).getSpecies() == "Perca flavescens"; + assert BioTree.getTaxonRecord(0).getSpecies() == "Morone chrysops"; + assert BioTree.getTaxonRecord(1).getSpecies() == "Perca flavescens"; } } diff --git a/src/biotree/WormsAPI.java b/src/biotree/WormsAPI.java index 39f47d3bc7b60c4e20f4a98791c82f71f7538905..2ae560cd0c2fe87c6c48130cd3ebc0d438ad4151 100644 --- a/src/biotree/WormsAPI.java +++ b/src/biotree/WormsAPI.java @@ -22,7 +22,7 @@ public class WormsAPI { public static void main(String[] args) throws IOException, ParseException { //small test - + System.out.println(nameToID("Neogobius melanostomus")); /* TaxonNode[] taxnodes = idToClassification(126916); @@ -73,6 +73,7 @@ public class WormsAPI { * @throws IOException * @throws ParseException */ +<<<<<<< HEAD public static TaxonNode[] idToClassification(int taxonId) throws IOException, ParseException { String resp = makeRequest(String.format("http://marinespecies.org/rest/AphiaClassificationByAphiaID/%d", taxonId)); JSONParser parser = new JSONParser(); @@ -84,6 +85,9 @@ public class WormsAPI { TaxonNode[] copiedArray = new TaxonNode[arraysize]; System.arraycopy(taxnodes, 0, copiedArray, 0, arraysize); +======= + public static TaxonNode[] idToClassification(int taxonId) { +>>>>>>> 7713da5ef410b951f64f9d9fda4937386132f0a0 return copiedArray; diff --git a/src/search/BST.java b/src/search/BST.java new file mode 100644 index 0000000000000000000000000000000000000000..2ec7e8a3cbaaa71e3e0447469386f19a013f8cdb --- /dev/null +++ b/src/search/BST.java @@ -0,0 +1,177 @@ +package search; + +import java.util.ArrayList; +import java.util.NoSuchElementException; + +public class BST<Key extends Comparable<Key>, Value> { + private Node root; + + private class Node{ + private Key key; + private Value val; + private Node left, right; + private int N; + + public Node(Key key, Value val, int N) { + this.key = key; + this.val = val; + this.N = N; + } + } + + public int size() { + return size(root); + } + + private int size(Node x) { + if (x == null) return 0; + else return x.N; + } + + public Value get(Key key) { return get(root, key); } + + private Value get(Node x, Key key) { + if (x == null) return null; + int cmp = key.compareTo(x.key); + if (cmp < 0) return get(x.left, key); + else if (cmp > 0) return get(x.right, key); + else return x.val; + } + + public void put(Key key, Value val) { + root = put(root, key, val); + } + + private Node put(Node x, Key key, Value val) { + if (x == null) return new Node(key, val, 1); + + int cmp = key.compareTo(x.key); + + if (cmp < 0) x.left = put(x.left, key, val); + else if (cmp > 0) x.right = put(x.right, key, val); + else x.val = val; + + x.N = size(x.left) + size(x.right) + 1; + return x; + } + + public boolean isEmpty() { + return root == null; + } + + public Key min() { + if (isEmpty()) throw new NoSuchElementException(); + Node x = min(root); + return x.key; + } + + private Node min(Node x) { + if (x.left == null) return x; + return min(x.left); + } + + public Key max() { + if (isEmpty()) throw new NoSuchElementException(); + Node x = max(root); + return x.key; + } + + private Node max(Node x) { + if (x.right == null) return x; + return max(x.right); + } + + public Key floor(Key key) { + Node x = floor(root, key); + if (x == null) throw new NoSuchElementException(); + return x.key; + } + + private Node floor(Node x, Key key) { + if (x == null) return null; + int cmp = key.compareTo(x.key); + if (cmp == 0) return x; + if (cmp < 0) return floor(x.left, key); + Node t = floor(x.right, key); + if (t != null) return t; + else return x; + } + + public Key select(int k) { + if (k < 0 || k >= size()) throw new IllegalArgumentException(); + Node x = select(root, k); + return x.key; + } + + private Node select(Node x, int k) { + if (x == null) return null; + int t = size(x.left); + if (t > k) return select(x.left, k); + else if (t < k) return select(x.right, k - t -1); + else return x; + } + + public int rank(Key key) { + return rank(key, root); + } + + private int rank(Key key, Node x) { + if (x == null) return 0; + int cmp = key.compareTo(x.key); + if (cmp < 0) return rank(key, x.left); + else if (cmp > 0) return 1 + size(x.left) + rank(key, x.right); + else return size(x.left); + } + + public void deleteMin() { + if (isEmpty()) throw new NoSuchElementException(); + root = deleteMin(root); + } + + private Node deleteMin(Node x) { + if (x.left == null) return x.right; + x.left = deleteMin(x.left); + x.N = size(x.left) + size(x.right) + 1; + return x; + } + + public void delete(Key key) { + root = delete(root, key); + } + + private Node delete(Node x, Key key) { + if (x == null) return null; + int cmp = key.compareTo(x.key); + if (cmp < 0) x.left = delete(x.left, key); + else if (cmp > 0) x.right = delete(x.right, key); + else { + if (x.right == null) return x.left; + if (x.left == null) return x.right; + Node t = x; + x = min(t.right); + x.right = deleteMin(t.right); + x.left = t.left; + } + x.N = size(x.left) + size(x.right) + 1; + return x; + } + + public Iterable<Key> keys() { + return keys(min(), max()); + } + + public Iterable<Key> keys(Key lo, Key hi) { + ArrayList<Key> al = new ArrayList<Key>(); + keys(root, al, lo, hi); + return al; + } + + private void keys(Node x, ArrayList<Key> al, Key lo, Key hi) { + if (x == null) return; + int cmplo = lo.compareTo(x.key); + int cmphi = hi.compareTo(x.key); + if (cmplo < 0) keys(x.left, al, lo, hi); + if (cmplo <= 0 && cmphi >= 0) al.add(x.key); + if (cmphi > 0) keys(x.right, al, lo, hi); + } +}