From 390b0cdaf1c1abefff237869a62311f9cd4ca104 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 14 Mar 2018 00:19:20 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B1=D0=BE=D1=80=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw_01/.gitignore | 1 + hw_01/pom.xml | 25 +++++ hw_01/src/main/java/hw_01/Bor.java | 100 ++++++++++++++++++++ hw_01/src/main/java/hw_01/Trie.java | 32 +++++++ hw_01/src/test/java/hw_01/TrieImplTest.java | 79 ++++++++++++++++ 5 files changed, 237 insertions(+) create mode 100644 hw_01/.gitignore create mode 100644 hw_01/pom.xml create mode 100644 hw_01/src/main/java/hw_01/Bor.java create mode 100644 hw_01/src/main/java/hw_01/Trie.java create mode 100644 hw_01/src/test/java/hw_01/TrieImplTest.java diff --git a/hw_01/.gitignore b/hw_01/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/hw_01/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/hw_01/pom.xml b/hw_01/pom.xml new file mode 100644 index 0000000..5b6a436 --- /dev/null +++ b/hw_01/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + 1 + hw_01 + 0.0.1-SNAPSHOT + jar + + hw_01 + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + diff --git a/hw_01/src/main/java/hw_01/Bor.java b/hw_01/src/main/java/hw_01/Bor.java new file mode 100644 index 0000000..0c82bab --- /dev/null +++ b/hw_01/src/main/java/hw_01/Bor.java @@ -0,0 +1,100 @@ +package hw_01; + +public class Bor implements Trie { + public Bor() { + bor = new Node(); + } + + public boolean add(String element) { + if (contains(element)) { + return false; + } + + Node p = bor; + p.nwords++; + for (int i = 0; i < element.length(); i++) { + if (p.lifes[arr_num(element.charAt(i))] == null) { + p.lifes[arr_num(element.charAt(i))] = new Node(); + size++; + } + p = p.lifes[arr_num(element.charAt(i))]; + p.nwords++; + } + + p.isTerminal = true; + return true; + } + + public boolean contains(String element) { + Node p = bor; + for (int i = 0; i < element.length(); i++) { + if (p.lifes[arr_num(element.charAt(i))] == null) { + return false; + } + p = p.lifes[arr_num(element.charAt(i))]; + } + + if (p.isTerminal) { + return true; + } + + return false; + } + + public boolean remove(String element) { + if (!contains(element)) { + return false; + } + + Node p = bor; + p.nwords--; + for (int i = 0; i < element.length(); i++) { + if (p.lifes[arr_num(element.charAt(i))].nwords == 1) { + size -= element.length() - i; + p.lifes[arr_num(element.charAt(i))] = null; + return true; + } + p = p.lifes[arr_num(element.charAt(i))]; + p.nwords--; + } + + p.isTerminal = false; + + return true; + } + + public int size() { + return size; + } + + public int howManyStartsWithPrefix(String prefix) { + Node p = bor; + for (int i = 0; i < prefix.length(); i++) { + if (p.lifes[arr_num(prefix.charAt(i))] == null) { + return 0; + } + p = p.lifes[arr_num(prefix.charAt(i))]; + } + + return p.nwords; + } + + private Node bor; + private int size = 0; + private int arr_num(char a) { + if ('a' <= a && a <= 'z') { + return a - 'a'; + } + + if ('A' <= a && a <= 'Z') { + return a - 'A' + 'z' - 'a' + 1; + } + + return -1; + } + private class Node { + public boolean isTerminal; + public int nwords; + Node[] lifes = new Node[2*('z' - 'a' + 1)]; + } +} diff --git a/hw_01/src/main/java/hw_01/Trie.java b/hw_01/src/main/java/hw_01/Trie.java new file mode 100644 index 0000000..5c043b4 --- /dev/null +++ b/hw_01/src/main/java/hw_01/Trie.java @@ -0,0 +1,32 @@ +package hw_01; + +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); +} diff --git a/hw_01/src/test/java/hw_01/TrieImplTest.java b/hw_01/src/test/java/hw_01/TrieImplTest.java new file mode 100644 index 0000000..390fa6c --- /dev/null +++ b/hw_01/src/test/java/hw_01/TrieImplTest.java @@ -0,0 +1,79 @@ +package hw_01; + +import junit.framework.TestCase; + +public class TrieImplTest + extends TestCase +{ + private Bor b; + + public TrieImplTest() { + super(); + b = new Bor(); + } + + public void testBor() { + b = new Bor(); + //Добавление + assertFalse(b.contains("Hello")); + assertTrue(b.add("Hello")); + assertTrue(b.contains("Hello")); + assertEquals(5, b.size()); + assertFalse(b.add("Hello")); + assertEquals(5, b.size()); + assertFalse(b.contains("Hell")); + assertTrue(b.add("Hell")); + assertTrue(b.contains("Hell")); + assertEquals(5, b.size()); + assertFalse(b.add("Hell")); + assertEquals(5, b.size()); + assertFalse(b.contains("Head")); + assertTrue(b.add("Head")); + assertTrue(b.contains("Head")); + assertEquals(7, b.size()); + assertFalse(b.contains("")); + assertTrue(b.add("")); + assertTrue(b.contains("")); + assertEquals(7, b.size()); + + //Проверка префиксов + assertEquals(3, b.howManyStartsWithPrefix("H")); + assertEquals(4, b.howManyStartsWithPrefix("")); + assertEquals(1, b.howManyStartsWithPrefix("Hea")); + assertEquals(2, b.howManyStartsWithPrefix("Hell")); + assertEquals(0, b.howManyStartsWithPrefix("h")); + + //Удаление + assertFalse(b.remove("h")); + assertFalse(b.remove("H")); + assertTrue(b.remove("Hell")); + assertFalse(b.remove("Hell")); + assertFalse(b.contains("Hell")); + assertEquals(7, b.size()); + assertEquals(1, b.howManyStartsWithPrefix("Hell")); + + assertTrue(b.remove("")); + assertFalse(b.remove("")); + assertEquals(7, b.size()); + assertEquals(2, b.howManyStartsWithPrefix("")); + + assertTrue(b.remove("Hello")); + assertFalse(b.remove("Hello")); + assertEquals(4, b.size()); + + assertTrue(b.contains("Head")); + assertTrue(b.add("HeadZzZ")); + assertEquals(7, b.size()); + assertEquals(2, b.howManyStartsWithPrefix("Head")); + assertEquals(1, b.howManyStartsWithPrefix("HeadZzZ")); + assertFalse(b.remove("HeadZ")); + assertTrue(b.remove("HeadZzZ")); + assertEquals(4, b.size()); + assertEquals(1, b.howManyStartsWithPrefix("Head")); + assertEquals(1, b.howManyStartsWithPrefix("")); + assertEquals(0, b.howManyStartsWithPrefix("HeadZ")); + + assertTrue(b.remove("Head")); + assertEquals(0, b.size()); + } +} From b0bec4bbde68294d751f06887fd36b0e4a8cf870 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 14 Mar 2018 00:38:08 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8E=20Java.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Теперь должен работать mvn test --- hw_01/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw_01/pom.xml b/hw_01/pom.xml index 5b6a436..307b47f 100644 --- a/hw_01/pom.xml +++ b/hw_01/pom.xml @@ -12,6 +12,8 @@ UTF-8 + 1.8 + 1.8 From 55aafe7c0b86bd1cd9fe8ad57d0011758b3c93a7 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 14 Mar 2018 00:44:24 +0300 Subject: [PATCH 3/4] .gitignore deleted --- hw_01/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 hw_01/.gitignore diff --git a/hw_01/.gitignore b/hw_01/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/hw_01/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ From dccdb821b47165da3b83f5e68c6a19ea92917b03 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 22 Mar 2018 00:17:31 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Разделил тесты на блоки. --- hw_01/src/main/java/hw_01/Bor.java | 45 ++++++++++------- hw_01/src/test/java/hw_01/TrieImplTest.java | 55 +++++++++++++++++---- 2 files changed, 72 insertions(+), 28 deletions(-) diff --git a/hw_01/src/main/java/hw_01/Bor.java b/hw_01/src/main/java/hw_01/Bor.java index 0c82bab..99997c9 100644 --- a/hw_01/src/main/java/hw_01/Bor.java +++ b/hw_01/src/main/java/hw_01/Bor.java @@ -1,6 +1,9 @@ package hw_01; public class Bor implements Trie { + final private Node bor; + private int size = 0; + public Bor() { bor = new Node(); } @@ -11,13 +14,16 @@ public boolean add(String element) { } Node p = bor; + p.nwords++; for (int i = 0; i < element.length(); i++) { - if (p.lifes[arr_num(element.charAt(i))] == null) { - p.lifes[arr_num(element.charAt(i))] = new Node(); + int currIdx = arrNum(element.charAt(i)); + + if (p.lifes[currIdx] == null) { + p.lifes[currIdx] = new Node(); size++; } - p = p.lifes[arr_num(element.charAt(i))]; + p = p.lifes[currIdx]; p.nwords++; } @@ -28,17 +34,15 @@ public boolean add(String element) { public boolean contains(String element) { Node p = bor; for (int i = 0; i < element.length(); i++) { - if (p.lifes[arr_num(element.charAt(i))] == null) { + int currIdx = arrNum(element.charAt(i)); + + if (p.lifes[currIdx] == null) { return false; } - p = p.lifes[arr_num(element.charAt(i))]; + p = p.lifes[currIdx]; } - - if (p.isTerminal) { - return true; - } - - return false; + + return p.isTerminal; } public boolean remove(String element) { @@ -49,12 +53,14 @@ public boolean remove(String element) { Node p = bor; p.nwords--; for (int i = 0; i < element.length(); i++) { - if (p.lifes[arr_num(element.charAt(i))].nwords == 1) { + int currIdx = arrNum(element.charAt(i)); + + if (p.lifes[currIdx].nwords == 1) { size -= element.length() - i; - p.lifes[arr_num(element.charAt(i))] = null; + p.lifes[currIdx] = null; return true; } - p = p.lifes[arr_num(element.charAt(i))]; + p = p.lifes[currIdx]; p.nwords--; } @@ -70,18 +76,18 @@ public int size() { public int howManyStartsWithPrefix(String prefix) { Node p = bor; for (int i = 0; i < prefix.length(); i++) { - if (p.lifes[arr_num(prefix.charAt(i))] == null) { + int currIdx = arrNum(prefix.charAt(i)); + + if (p.lifes[currIdx] == null) { return 0; } - p = p.lifes[arr_num(prefix.charAt(i))]; + p = p.lifes[currIdx]; } return p.nwords; } - private Node bor; - private int size = 0; - private int arr_num(char a) { + private int arrNum(char a) { if ('a' <= a && a <= 'z') { return a - 'a'; } @@ -92,6 +98,7 @@ private int arr_num(char a) { return -1; } + private class Node { public boolean isTerminal; public int nwords; diff --git a/hw_01/src/test/java/hw_01/TrieImplTest.java b/hw_01/src/test/java/hw_01/TrieImplTest.java index 390fa6c..51f60cf 100644 --- a/hw_01/src/test/java/hw_01/TrieImplTest.java +++ b/hw_01/src/test/java/hw_01/TrieImplTest.java @@ -2,18 +2,54 @@ import junit.framework.TestCase; -public class TrieImplTest - extends TestCase -{ +public class TrieImplTest extends TestCase { private Bor b; - - public TrieImplTest() { - super(); + + public void setUp() { b = new Bor(); } - - public void testBor() { - b = new Bor(); + + public void testAddSizeContains() { + assertFalse(b.contains("Hello")); + assertTrue(b.add("Hello")); + assertTrue(b.contains("Hello")); + assertEquals(5, b.size()); + assertEquals(1, b.howManyStartsWithPrefix("Hell")); + } + + public void testAddContainsPrefix() { + b.add("Hello"); + assertFalse(b.contains("Hell")); + assertTrue(b.add("Hell")); + assertTrue(b.contains("Hell")); + assertEquals(5, b.size()); + assertEquals(2, b.howManyStartsWithPrefix("Hell")); + } + + public void testAddOutstandingWord() { + b.add("Hello"); + assertTrue(b.add("Head")); + assertEquals(7, b.size()); + } + + public void testRemovePrefix() { + b.add("Hello"); + b.add("Hell"); + assertFalse(b.remove("He")); + assertTrue(b.remove("Hell")); + assertEquals(5, b.size()); + assertEquals(1, b.howManyStartsWithPrefix("Hell")); + } + + public void testTemoveSuffix() { + b.add("Hello"); + b.add("Hell"); + assertTrue(b.remove("Hello")); + assertEquals(4, b.size()); + } +/* + public void testBorBigTest() { + //b = new Bor(); //Добавление assertFalse(b.contains("Hello")); assertTrue(b.add("Hello")); @@ -76,4 +112,5 @@ public void testBor() { assertTrue(b.remove("Head")); assertEquals(0, b.size()); } +*/ }