From 4f29d209c865ac5ebdfe6b63c5e626d0791650ac Mon Sep 17 00:00:00 2001 From: Sangmin Jeon Date: Sun, 16 Jul 2023 20:11:13 +0900 Subject: [PATCH 1/3] Fix insertion fail in ["*X", "*XX"] cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consider a word, and a copy of that word, but with the last letter repeating twice. (e.g., ["ABC", "ABCC"]) When adding the second word's last letter, it only compares the previous word's prefix—the last letter of the word already in the Radix Tree: 'C'—and the letter to be added—the last letter of the word we're currently adding: 'C'. So it wrongly passes the "Case 1" check, marks the current node as a leaf node when it already was, then returns when there's still one more letter to add. The issue arises because `prefix` includes the letter of the node itself. (e.g., `nodes: {'C' : RadixNode()}, is_leaf: True, prefix: 'C'`) It can be easily fixed by simply adding the `is_leaf` check, asking if there are more letters to be added. - Test Case: `"A AA AAA AAAA"` - Fixed correct output: ``` Words: ['A', 'AA', 'AAA', 'AAAA'] Tree: - A (leaf) -- A (leaf) --- A (leaf) ---- A (leaf) ``` - Current incorrect output: ``` Words: ['A', 'AA', 'AAA', 'AAAA'] Tree: - A (leaf) -- AA (leaf) --- A (leaf) ``` *N.B.* This passed test cases for [Croatian Open Competition in Informatics 2012/2013 Contest #3 Task 5 HERKABE](https://hsin.hr/coci/archive/2012_2013/) --- data_structures/trie/radix_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/trie/radix_tree.py b/data_structures/trie/radix_tree.py index 66890346ec2b..fbf04f6e3357 100644 --- a/data_structures/trie/radix_tree.py +++ b/data_structures/trie/radix_tree.py @@ -57,7 +57,7 @@ def insert(self, word: str) -> None: """ # Case 1: If the word is the prefix of the node # Solution: We set the current node as leaf - if self.prefix == word: + if self.prefix == word and not self.is_leaf: self.is_leaf = True # Case 2: The node has no edges that have a prefix to the word From a5b986831bb672e6815e1151620dbfd4e224fb0a Mon Sep 17 00:00:00 2001 From: furthermares Date: Mon, 24 Jul 2023 17:54:13 +0900 Subject: [PATCH 2/3] Add a doctest for previous fix --- data_structures/trie/radix_tree.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data_structures/trie/radix_tree.py b/data_structures/trie/radix_tree.py index fbf04f6e3357..016e75328fc8 100644 --- a/data_structures/trie/radix_tree.py +++ b/data_structures/trie/radix_tree.py @@ -54,6 +54,11 @@ def insert(self, word: str) -> None: word (str): word to insert >>> RadixNode("myprefix").insert("mystring") + + >>> root = RadixNode() + >>> root.insert_many(['A', 'AA']) + >>> root.nodes['A'].nodes['A'].prefix + 'A' """ # Case 1: If the word is the prefix of the node # Solution: We set the current node as leaf From d918fcbf65d16f4d280639e04596c6d6b9ed6398 Mon Sep 17 00:00:00 2001 From: furthermares Date: Mon, 24 Jul 2023 18:23:36 +0900 Subject: [PATCH 3/3] improve doctest readability --- data_structures/trie/radix_tree.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/data_structures/trie/radix_tree.py b/data_structures/trie/radix_tree.py index 016e75328fc8..ddadb3ef996a 100644 --- a/data_structures/trie/radix_tree.py +++ b/data_structures/trie/radix_tree.py @@ -56,9 +56,11 @@ def insert(self, word: str) -> None: >>> RadixNode("myprefix").insert("mystring") >>> root = RadixNode() - >>> root.insert_many(['A', 'AA']) - >>> root.nodes['A'].nodes['A'].prefix - 'A' + >>> root.insert_many(['myprefix', 'myprefixA', 'myprefixAA']) + >>> root.print_tree() + - myprefix (leaf) + -- A (leaf) + --- A (leaf) """ # Case 1: If the word is the prefix of the node # Solution: We set the current node as leaf