From 371992a38d1972c9ae254c8317c8d0b8cf6ef938 Mon Sep 17 00:00:00 2001 From: roman Date: Fri, 26 Feb 2016 21:59:27 +0300 Subject: [PATCH] task1 --- hw01/sp/Trie.java | 32 +++++++ hw01/sp/TrieImpl.java | 96 ++++++++++++++++++++ hw01/sp/TrieTest.java | 197 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 325 insertions(+) create mode 100644 hw01/sp/Trie.java create mode 100644 hw01/sp/TrieImpl.java create mode 100644 hw01/sp/TrieTest.java diff --git a/hw01/sp/Trie.java b/hw01/sp/Trie.java new file mode 100644 index 0000000..4ebfd31 --- /dev/null +++ b/hw01/sp/Trie.java @@ -0,0 +1,32 @@ +package sp; + +public interface Trie { + + /** + * Expected complexity: O(|element|) + * @return true if this set did not already contain the specified + * element + */ + boolean add(String element); + + /** + * Expected complexity: O(|element|) + */ + boolean contains(String element); + + /** + * Expected complexity: O(|element|) + * @return true if this set contained the specified element + */ + boolean remove(String element); + + /** + * Expected complexity: O(1) + */ + int size(); + + /** + * Expected complexity: O(|prefix|) + */ + int howManyStartsWithPrefix(String prefix); +} \ No newline at end of file diff --git a/hw01/sp/TrieImpl.java b/hw01/sp/TrieImpl.java new file mode 100644 index 0000000..975b358 --- /dev/null +++ b/hw01/sp/TrieImpl.java @@ -0,0 +1,96 @@ +package sp; + +import java.lang.Character; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.TreeSet; +import java.util.Map; + +public class TrieImpl implements Trie { + + Node root = new Node(); + + public boolean add(String element) { + Node node = root; + for(char c : element.toCharArray()) + node = node.next(c); + return node.setLeaf(true); + } + + public boolean contains(String element) { + Node node = root; + for(char c : element.toCharArray()) { + if (!node.containsKey(c)) + return false; + node = node.get(c); + } + return node.isLeaf(); + } + + public boolean remove(String element) { + Node node = root; + for(char c : element.toCharArray()) { + if (!node.containsKey(c)) + return false; + node = node.get(c); + } + return node.setLeaf(false); + } + + public int size() { + return root.getSize(); + } + + public int howManyStartsWithPrefix(String prefix) { + Node node = root; + for(char c : prefix.toCharArray()) { + if (!node.containsKey(c)) + return 0; + node = node.get(c); + } + return node.getSize(); + } + + private class Node extends HashMap { + + private int wordCount = 0; + private boolean isLeaf = false; + private WeakReference parrent = null; + private Character character = null; + + public Node() {} + + public Node(Node prev, Character c) { + parrent = new WeakReference<>(prev); + character = c; + } + + public Node next(Character key) { + if (!containsKey(key)) + put(key, new Node(this, key)); + return get(key); + } + + public int getSize() { return wordCount; } + + private void updateSize(Character c, int delta) { + if (c != null && get(c).getSize() == 0) { + remove(c); + } + wordCount += delta; + if (parrent != null) + parrent.get().updateSize(this.character, delta); + } + + boolean isLeaf() { return isLeaf; } + + boolean setLeaf(boolean value) { + if (isLeaf == value) + return false; + isLeaf = value; + updateSize(null, value ? 1 : -1); + return true; + } + + } +} \ No newline at end of file diff --git a/hw01/sp/TrieTest.java b/hw01/sp/TrieTest.java new file mode 100644 index 0000000..d0012dd --- /dev/null +++ b/hw01/sp/TrieTest.java @@ -0,0 +1,197 @@ +package sp; + +import static org.junit.Assert.*; + +public class TrieTest { + + @org.junit.Test + public void testAdd() throws Exception { + Trie trie = new TrieImpl(); + + assertTrue(trie.add("")); + assertTrue(trie.add("aa")); + assertTrue(trie.add("a")); + assertTrue(trie.add("aaa")); + assertTrue(trie.add("aab")); + assertTrue(trie.add("aac")); + assertTrue(trie.add("ab")); + + assertFalse(trie.add("")); + assertFalse(trie.add("aa")); + assertFalse(trie.add("a")); + assertFalse(trie.add("aaa")); + assertFalse(trie.add("aab")); + assertFalse(trie.add("aac")); + assertFalse(trie.add("ab")); + + trie.remove(""); + trie.remove("aab"); + + assertTrue(trie.add("aaaa")); + assertFalse(trie.add("aaaa")); + + trie.remove("a"); + trie.remove("aa"); + trie.remove("aaa"); + trie.remove("aac"); + trie.remove("ab"); + } + + @org.junit.Test + public void testRemove() throws Exception { + Trie trie = new TrieImpl(); + assertFalse(trie.contains("")); + trie.add(""); + trie.add("aa"); + trie.add("a"); + trie.add("aaa"); + trie.add("aab"); + trie.add("aac"); + trie.add("ab"); + assertTrue(trie.remove("")); + assertTrue(trie.remove("aab")); + trie.add("aaaa"); + assertTrue(trie.remove("a")); + assertTrue(trie.remove("aa")); + assertTrue(trie.remove("aaa")); + assertTrue(trie.remove("aac")); + assertTrue(trie.remove("ab")); + + assertFalse(trie.remove("")); + assertFalse(trie.remove("aab")); + assertFalse(trie.remove("")); + assertFalse(trie.remove("aab")); + assertFalse(trie.remove("a")); + assertFalse(trie.remove("aa")); + assertFalse(trie.remove("aaa")); + assertFalse(trie.remove("aac")); + assertFalse(trie.remove("ab")); + } + + @org.junit.Test + public void testContains() throws Exception { + Trie trie = new TrieImpl(); + assertFalse(trie.contains("")); + trie.add(""); + trie.add("aa"); + trie.add("a"); + trie.add("aaa"); + trie.add("aab"); + trie.add("aac"); + trie.add("ab"); + + assertTrue(trie.contains("")); + assertTrue(trie.contains("aa")); + assertTrue(trie.contains("a")); + assertTrue(trie.contains("aaa")); + assertTrue(trie.contains("aab")); + assertTrue(trie.contains("aac")); + assertTrue(trie.contains("ab")); + + trie.remove(""); + trie.remove("aab"); + + assertFalse(trie.contains("")); + assertTrue(trie.contains("aa")); + assertTrue(trie.contains("a")); + assertTrue(trie.contains("aaa")); + assertFalse(trie.contains("aab")); + assertTrue(trie.contains("aac")); + assertTrue(trie.contains("ab")); + + trie.add("aaaa"); + trie.remove("a"); + trie.remove("aa"); + trie.remove("aaa"); + trie.remove("aac"); + trie.remove("ab"); + + assertFalse(trie.contains("")); + assertFalse(trie.contains("aa")); + assertFalse(trie.contains("a")); + assertFalse(trie.contains("aaa")); + assertFalse(trie.contains("aab")); + assertFalse(trie.contains("aac")); + assertFalse(trie.contains("ab")); + assertTrue(trie.contains("aaaa")); + } + + @org.junit.Test + public void testSize() throws Exception { + Trie trie = new TrieImpl(); + + assertEquals(trie.size(), 0); + trie.add(""); + assertEquals(trie.size(), 1); + trie.add("aa"); + trie.add("a"); + trie.add("aaa"); + assertEquals(trie.size(), 4); + trie.add("aab"); + trie.add("aac"); + trie.add("ab"); + assertEquals(trie.size(), 7); + + trie.remove(""); + trie.remove("aab"); + assertEquals(trie.size(), 5); + + trie.add("aaaa"); + assertEquals(trie.size(), 6); + + trie.remove("a"); + trie.remove("aa"); + trie.remove("aaa"); + assertEquals(trie.size(), 3); + trie.remove("aac"); + trie.remove("ab"); + assertEquals(trie.size(), 1); + + } + + @org.junit.Test + public void testHowManyStartsWithPrefix() throws Exception { + Trie trie = new TrieImpl(); + + assertEquals(trie.howManyStartsWithPrefix(""), 0); + assertEquals(trie.howManyStartsWithPrefix("a"), 0); + assertEquals(trie.howManyStartsWithPrefix("aa"), 0); + assertEquals(trie.howManyStartsWithPrefix("aaa"), 0); + + trie.add(""); + trie.add("aa"); + trie.add("a"); + trie.add("aaa"); + trie.add("aab"); + trie.add("aac"); + trie.add("ab"); + + assertEquals(trie.howManyStartsWithPrefix(""), 7); + assertEquals(trie.howManyStartsWithPrefix("a"), 6); + assertEquals(trie.howManyStartsWithPrefix("aa"), 4); + assertEquals(trie.howManyStartsWithPrefix("aaa"), 1); + + trie.remove(""); + trie.remove("aab"); + + trie.add("aaaa"); + + assertEquals(trie.howManyStartsWithPrefix(""), 6); + assertEquals(trie.howManyStartsWithPrefix("a"), 6); + assertEquals(trie.howManyStartsWithPrefix("aa"), 4); + assertEquals(trie.howManyStartsWithPrefix("aaa"), 2); + + trie.remove("a"); + trie.remove("aa"); + trie.remove("aaa"); + trie.remove("aac"); + trie.remove("ab"); + + assertEquals(trie.howManyStartsWithPrefix(""), 1); + assertEquals(trie.howManyStartsWithPrefix("a"), 1); + assertEquals(trie.howManyStartsWithPrefix("aa"), 1); + assertEquals(trie.howManyStartsWithPrefix("aaa"), 1); + } + + +} \ No newline at end of file