From f543529fe82606ab92c4f5a0af81ee92a8b7531d Mon Sep 17 00:00:00 2001 From: Otkuda Date: Sun, 13 Feb 2022 13:04:20 +0300 Subject: [PATCH 1/3] Prefix Trie class --- src/main/java/Triangle.java | 21 ------ src/main/java/Trie.java | 115 ++++++++++++++++++++++++++++++++ src/test/java/TriangleTest.java | 13 ---- src/test/java/TrieTest.java | 11 +++ 4 files changed, 126 insertions(+), 34 deletions(-) delete mode 100644 src/main/java/Triangle.java create mode 100644 src/main/java/Trie.java delete mode 100644 src/test/java/TriangleTest.java create mode 100644 src/test/java/TrieTest.java diff --git a/src/main/java/Triangle.java b/src/main/java/Triangle.java deleted file mode 100644 index c402cde..0000000 --- a/src/main/java/Triangle.java +++ /dev/null @@ -1,21 +0,0 @@ -public class Triangle { - - private final int a; - private final int b; - private final int c; - - public Triangle(int a, int b, int c) { - this.a = a; - this.b = b; - this.c = c; - } - - public double calcSquare() { - int p = calcPerimeter(); - return Math.sqrt(p * (p - a) * (p - b) * (p - c)); - } - - public int calcPerimeter() { - return a + b + c; - } -} diff --git a/src/main/java/Trie.java b/src/main/java/Trie.java new file mode 100644 index 0000000..d13a17a --- /dev/null +++ b/src/main/java/Trie.java @@ -0,0 +1,115 @@ +import java.util.*; + + +public class Trie { + TrieNode root; + + Trie () { + root = new TrieNode(' '); + } + + public boolean ifExist(String word) { + TrieNode curr = root; + for (char c:word.toCharArray()) { + if (curr.getChild(c) == null) return false; + else curr = curr.getChild(c); + } + return curr.isLastSymbol; + } + + public void printIfExist(String word) { + if (ifExist(word)) System.out.printf("Слово \"%s\" найдено\n", word); + else System.out.printf("Слово \"%s\" не найдено\n", word); + } + + + public void add(String word) { + if (ifExist(word) || word.length() == 0) return; + TrieNode curr = root; + var chars = word.toCharArray(); + for (int i = 0; i < chars.length; i++) { + TrieNode child = curr.getChild(chars[i]); + if (child != null) curr = child; + else { + curr.children.add(new TrieNode(chars[i])); + curr = curr.getChild(chars[i]); + } + curr.count++; + curr.text = word.substring(0, i + 1); + } + curr.isLastSymbol = true; + } + + public void remove(String word) { + if (!ifExist(word) || word.length() == 0) return; + TrieNode curr = root; + char[] chars = word.toCharArray(); + for (char c : chars) { + TrieNode child = curr.getChild(c); + if (child.count == 1) { + curr.children.remove(child); + return; + } else { + child.count--; + curr = child; + } + } + curr.isLastSymbol = false; + } + + public ArrayList prefixSearch(String prefix) { + TrieNode curr = root; + for(char c:prefix.toCharArray()) { + curr = curr.getChild(c); + if(curr == null) return null; + } + return allWords(curr); + } + + private ArrayList allWords(TrieNode node) { + if (node == null) return null; + ArrayList res = new ArrayList<>(); + if (node.isLastSymbol) res.add(node.text); + for (TrieNode child:node.children) { + res.addAll(allWords(node.getChild(child.value))); + } + return res; + } + + + public static void main(String[] args) { + Trie t = new Trie(); + t.add("qer"); + t.add("qre"); + t.add("qaw"); + t.add("qawr"); + t.printIfExist("qaw"); + t.remove("qaw"); + t.printIfExist("qaw"); + System.out.println(t.prefixSearch("q")); + } +} + +class TrieNode { + char value; + ArrayList children; + boolean isLastSymbol; + int count; + String text; + + TrieNode(char value) { + this.value = value; + isLastSymbol = false; + children = new ArrayList<>(); + count = 0; + } + + public TrieNode getChild(char input) { + if (children != null) { + for (TrieNode child : children) { + if (child.value == input) return child; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/test/java/TriangleTest.java b/src/test/java/TriangleTest.java deleted file mode 100644 index b743089..0000000 --- a/src/test/java/TriangleTest.java +++ /dev/null @@ -1,13 +0,0 @@ -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -public class TriangleTest { - - @Test - public void testTriangleSquare() { - Triangle triangle = new Triangle(1, 1, 1); - double expectedSquare = 5; - assertEquals(expectedSquare, Math.round(triangle.calcSquare())); - } -} diff --git a/src/test/java/TrieTest.java b/src/test/java/TrieTest.java new file mode 100644 index 0000000..0c7a3f1 --- /dev/null +++ b/src/test/java/TrieTest.java @@ -0,0 +1,11 @@ +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class TrieTest { + + @Test + public void testTriangleSquare() { + + } +} From c7e101c7a57ba81f47110d825f8a3466392ae341 Mon Sep 17 00:00:00 2001 From: Otkuda Date: Fri, 18 Feb 2022 17:27:52 +0300 Subject: [PATCH 2/3] Method equals, toString and hashCode for Trie structure implemented. Test for add method done. --- src/main/java/Trie.java | 32 ++++++++++++++++++++++++++++---- src/test/java/TrieTest.java | 24 ++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/main/java/Trie.java b/src/main/java/Trie.java index d13a17a..3a7a9d2 100644 --- a/src/main/java/Trie.java +++ b/src/main/java/Trie.java @@ -1,16 +1,20 @@ import java.util.*; +import static java.util.Objects.hash; + public class Trie { TrieNode root; + ArrayList words; Trie () { root = new TrieNode(' '); + words = new ArrayList<>(); } public boolean ifExist(String word) { TrieNode curr = root; - for (char c:word.toCharArray()) { + for (char c:word.toLowerCase().toCharArray()) { if (curr.getChild(c) == null) return false; else curr = curr.getChild(c); } @@ -26,7 +30,7 @@ public void printIfExist(String word) { public void add(String word) { if (ifExist(word) || word.length() == 0) return; TrieNode curr = root; - var chars = word.toCharArray(); + var chars = word.toLowerCase().toCharArray(); for (int i = 0; i < chars.length; i++) { TrieNode child = curr.getChild(chars[i]); if (child != null) curr = child; @@ -38,12 +42,13 @@ public void add(String word) { curr.text = word.substring(0, i + 1); } curr.isLastSymbol = true; + words.add(word); } public void remove(String word) { if (!ifExist(word) || word.length() == 0) return; TrieNode curr = root; - char[] chars = word.toCharArray(); + char[] chars = word.toLowerCase().toCharArray(); for (char c : chars) { TrieNode child = curr.getChild(c); if (child.count == 1) { @@ -55,11 +60,12 @@ public void remove(String word) { } } curr.isLastSymbol = false; + words.remove(word); } public ArrayList prefixSearch(String prefix) { TrieNode curr = root; - for(char c:prefix.toCharArray()) { + for(char c:prefix.toLowerCase().toCharArray()) { curr = curr.getChild(c); if(curr == null) return null; } @@ -76,6 +82,23 @@ private ArrayList allWords(TrieNode node) { return res; } + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Trie t = (Trie) obj; + return this.words.equals(t.words); + } + + @Override + public String toString() { + return this.words.toString(); + } + + @Override + public int hashCode() { + return hash(this.words); + } public static void main(String[] args) { Trie t = new Trie(); @@ -83,6 +106,7 @@ public static void main(String[] args) { t.add("qre"); t.add("qaw"); t.add("qawr"); + t.add("Qawr"); t.printIfExist("qaw"); t.remove("qaw"); t.printIfExist("qaw"); diff --git a/src/test/java/TrieTest.java b/src/test/java/TrieTest.java index 0c7a3f1..29f701a 100644 --- a/src/test/java/TrieTest.java +++ b/src/test/java/TrieTest.java @@ -1,11 +1,31 @@ -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class TrieTest { + Trie trie1 = new Trie(); + Trie trie2 = new Trie(); + + @Test + public void testIfExist() { + trie1.add("qq"); + assertTrue(trie1.ifExist("qq")); + assertFalse(trie1.ifExist("a")); + assertTrue(trie1.ifExist("QQ")); + } + + @Test + public void testAdd() { + trie1.add("a"); + trie2.add("a"); + assertEquals(trie1, trie2); + trie2.add("b"); + assertNotEquals(trie1, trie2); + } + @Test - public void testTriangleSquare() { + public void testRemove() { } } From 0828e924af305b48a0b72792f3eeee38812b0892 Mon Sep 17 00:00:00 2001 From: Otkuda Date: Tue, 22 Feb 2022 09:47:58 +0300 Subject: [PATCH 3/3] Tests done --- src/main/java/Trie.java | 25 ++++++++++++------------- src/test/java/TrieTest.java | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/main/java/Trie.java b/src/main/java/Trie.java index 3a7a9d2..97f4343 100644 --- a/src/main/java/Trie.java +++ b/src/main/java/Trie.java @@ -14,7 +14,7 @@ public class Trie { public boolean ifExist(String word) { TrieNode curr = root; - for (char c:word.toLowerCase().toCharArray()) { + for (char c:word.trim().toLowerCase().toCharArray()) { if (curr.getChild(c) == null) return false; else curr = curr.getChild(c); } @@ -42,17 +42,18 @@ public void add(String word) { curr.text = word.substring(0, i + 1); } curr.isLastSymbol = true; - words.add(word); + words.add(word.trim().toLowerCase()); } public void remove(String word) { - if (!ifExist(word) || word.length() == 0) return; + if (!ifExist(word) || word.trim().length() == 0) return; TrieNode curr = root; - char[] chars = word.toLowerCase().toCharArray(); + char[] chars = word.trim().toLowerCase().toCharArray(); for (char c : chars) { TrieNode child = curr.getChild(c); if (child.count == 1) { curr.children.remove(child); + words.remove(word); return; } else { child.count--; @@ -60,7 +61,7 @@ public void remove(String word) { } } curr.isLastSymbol = false; - words.remove(word); + words.remove(word.trim().toLowerCase()); } public ArrayList prefixSearch(String prefix) { @@ -102,15 +103,13 @@ public int hashCode() { public static void main(String[] args) { Trie t = new Trie(); + Trie t1 = new Trie(); t.add("qer"); - t.add("qre"); - t.add("qaw"); - t.add("qawr"); - t.add("Qawr"); - t.printIfExist("qaw"); - t.remove("qaw"); - t.printIfExist("qaw"); - System.out.println(t.prefixSearch("q")); + t1.add("qer"); + t1.add("qaw"); + System.out.println(t1.words); + t1.remove("qaw"); + System.out.println(t1.words); } } diff --git a/src/test/java/TrieTest.java b/src/test/java/TrieTest.java index 29f701a..b9a069b 100644 --- a/src/test/java/TrieTest.java +++ b/src/test/java/TrieTest.java @@ -2,6 +2,9 @@ import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.List; + public class TrieTest { Trie trie1 = new Trie(); @@ -13,12 +16,15 @@ public void testIfExist() { assertTrue(trie1.ifExist("qq")); assertFalse(trie1.ifExist("a")); assertTrue(trie1.ifExist("QQ")); + assertFalse(trie1.ifExist(" ")); } @Test public void testAdd() { trie1.add("a"); + trie1.add("aaa"); trie2.add("a"); + trie2.add(" aAa "); assertEquals(trie1, trie2); trie2.add("b"); assertNotEquals(trie1, trie2); @@ -26,6 +32,25 @@ public void testAdd() { @Test public void testRemove() { + trie1.add("a"); + trie2.add("a"); + assertEquals(trie1, trie2); + trie1.remove("a"); + assertNotEquals(trie1, trie2); + } + @Test + public void testPrefixSearch() { + String[] resAr = {"maxwell", "mendel", "mendeleev"}; + String[] resAr1 = {"mendel", "mendeleev"}; + trie1.add("maxwell"); + trie1.add("mendel"); + trie1.add("mendeleev"); + trie1.add("pavlov"); + trie1.add("pasteur"); + trie1.add("poincare"); + trie1.add("turing"); + assertEquals(trie1.prefixSearch("m"), List.of(resAr)); + assertEquals(trie1.prefixSearch("men"), List.of(resAr1)); } }