Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced Trie Data Structure with Case-Insensitive Feature and additional Test Cases #172

Merged
merged 50 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
643dfa2
Added Disjoint Sets Data structure
Ramy-Badr-Ahmed Aug 24, 2024
7cfc859
Moved DisjointSetTest.php to tests/DataStructures
Ramy-Badr-Ahmed Sep 8, 2024
b3a8d7a
Update DataStructures/DisjointSets/DisjointSet.php
Ramy-Badr-Ahmed Sep 11, 2024
b6ae103
Update DataStructures/DisjointSets/DisjointSetNode.php
Ramy-Badr-Ahmed Sep 11, 2024
70d981a
Update DataStructures/DisjointSets/DisjointSetNode.php
Ramy-Badr-Ahmed Sep 11, 2024
dc93e41
Update tests/DataStructures/DisjointSetTest.php
Ramy-Badr-Ahmed Sep 11, 2024
35aa7d0
Update tests/DataStructures/DisjointSetTest.php
Ramy-Badr-Ahmed Sep 11, 2024
0591a6f
Update tests/DataStructures/DisjointSetTest.php
Ramy-Badr-Ahmed Sep 11, 2024
b0086fd
Considered PHPCS remarks. Unit Testing is now working.
Ramy-Badr-Ahmed Sep 11, 2024
b2d1160
Remove data type mixed. Considered annotations for php7.4.
Ramy-Badr-Ahmed Sep 11, 2024
926126a
Remove data type mixed. Considered annotations for php7.4.
Ramy-Badr-Ahmed Sep 11, 2024
355c5ba
updating DIRECTORY.md
Ramy-Badr-Ahmed Sep 11, 2024
99e489e
Merge branch 'TheAlgorithms:master' into master
Ramy-Badr-Ahmed Sep 11, 2024
db5bfb2
Merge branch 'TheAlgorithms:master' into master
Ramy-Badr-Ahmed Sep 14, 2024
bc44199
Implemented Trie DataStructure
Ramy-Badr-Ahmed Sep 14, 2024
b056238
Added Trie to DIRECTORY.md
Ramy-Badr-Ahmed Sep 14, 2024
5a02302
updating DIRECTORY.md
Ramy-Badr-Ahmed Sep 14, 2024
9c76b4b
Implemented AVLTree DataStructure
Ramy-Badr-Ahmed Sep 14, 2024
5330978
Merge branch 'features/avl-tree-implementation'
Ramy-Badr-Ahmed Sep 14, 2024
d258e77
updating DIRECTORY.md
Ramy-Badr-Ahmed Sep 14, 2024
9766ed8
Implemented AVLTree DataStructure
Ramy-Badr-Ahmed Sep 14, 2024
f701b1b
Merge branch 'features/avl-tree-implementation'
Ramy-Badr-Ahmed Sep 14, 2024
5f74e0e
Merge branch 'TheAlgorithms:master' into master
Ramy-Badr-Ahmed Sep 18, 2024
a8ca30f
Implemented SegmentTreeNode.php
Ramy-Badr-Ahmed Sep 21, 2024
ba43a0d
Implementing SegmentTree
Ramy-Badr-Ahmed Sep 22, 2024
ee1c6f6
Implementing SegmentTree with updateTree
Ramy-Badr-Ahmed Sep 22, 2024
6912710
Implementing SegmentTree with rangeUpdateTree
Ramy-Badr-Ahmed Sep 22, 2024
4d951d1
Implementing SegmentTree with query and queryTree
Ramy-Badr-Ahmed Sep 22, 2024
f741301
Added serializing and deserializing of the SegmentTree
Ramy-Badr-Ahmed Sep 22, 2024
4cef497
Adding unit tests SegmentTree implementation
Ramy-Badr-Ahmed Sep 22, 2024
be41540
Added unit tests for SegmentTree updates and range updates
Ramy-Badr-Ahmed Sep 22, 2024
0fed0ad
considering PHPCS for Added unit tests for SegmentTree updates and ra…
Ramy-Badr-Ahmed Sep 22, 2024
850fc4b
Added unit tests for SegmentTree serialization/deserialization and ar…
Ramy-Badr-Ahmed Sep 22, 2024
eca9709
Added unit tests for SegmentTree Edge Cases
Ramy-Badr-Ahmed Sep 22, 2024
628fc88
Added unit tests for SegmentTree Exceptions (OutOfBoundsException, In…
Ramy-Badr-Ahmed Sep 22, 2024
7d0c07d
Added SegmentTree to DIRECTORY.md
Ramy-Badr-Ahmed Sep 22, 2024
d61d023
Implemented Segment Tree Data Structure
Ramy-Badr-Ahmed Sep 22, 2024
eaa6bb7
updating DIRECTORY.md
Ramy-Badr-Ahmed Sep 22, 2024
f0acc06
Added some comments to my files in: #160, #162, #163, #166. Implement…
Ramy-Badr-Ahmed Sep 28, 2024
4eb689c
Merge branch 'features/segment-tree-implementation'
Ramy-Badr-Ahmed Sep 28, 2024
8957dd3
Added some comments to my files in: #160, #162, #163, #166. Implement…
Ramy-Badr-Ahmed Sep 28, 2024
e4cadc8
Merge branch 'features/segment-tree-implementation'
Ramy-Badr-Ahmed Sep 28, 2024
98a41ee
Added comments time complexity for query(), update() and buildTree()
Ramy-Badr-Ahmed Sep 30, 2024
6c64c35
Merge branch 'features/segment-tree-implementation'
Ramy-Badr-Ahmed Sep 30, 2024
ff94feb
Merge branch 'TheAlgorithms:master' into master
Ramy-Badr-Ahmed Oct 1, 2024
65c4849
Implemented Splay Tree Data Structure
Ramy-Badr-Ahmed Oct 3, 2024
5bb6777
Update tests/DataStructures/SplayTreeTest.php
Ramy-Badr-Ahmed Oct 3, 2024
8c6dd2c
Merge branch 'TheAlgorithms:master' into features/splay-tree-implemen…
Ramy-Badr-Ahmed Oct 3, 2024
d11e757
Merge branch 'TheAlgorithms:master' into master
Ramy-Badr-Ahmed Oct 7, 2024
c8376de
Implemented Trie Data Structure. Added case-insensitive feature to th…
Ramy-Badr-Ahmed Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DataStructures/Trie/Trie.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?php

/*
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #162
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request #162 and #172
* https://github.com/TheAlgorithms/PHP/pull/162
* https://github.com/TheAlgorithms/PHP/pull/172
*
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
* Thank you!
Expand Down Expand Up @@ -61,6 +62,7 @@ public function search(string $word): bool
*/
public function startsWith(string $prefix): array
{
$prefix = strtolower($prefix); // Normalize the prefix to lowercase
$node = $this->root;
for ($i = 0; $i < strlen($prefix); $i++) {
$char = $prefix[$i];
Expand Down
14 changes: 13 additions & 1 deletion DataStructures/Trie/TrieNode.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?php

/*
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #162
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request #162 and #172
* https://github.com/TheAlgorithms/PHP/pull/162
* https://github.com/TheAlgorithms/PHP/pull/172
*
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
* Thank you!
Expand All @@ -27,6 +28,7 @@ public function __construct()
*/
public function addChild(string $char): TrieNode
{
$char = $this->normalizeChar($char);
if (!isset($this->children[$char])) {
$this->children[$char] = new TrieNode();
}
Expand All @@ -38,6 +40,7 @@ public function addChild(string $char): TrieNode
*/
public function hasChild(string $char): bool
{
$char = $this->normalizeChar($char);
return isset($this->children[$char]);
}

Expand All @@ -46,6 +49,15 @@ public function hasChild(string $char): bool
*/
public function getChild(string $char): ?TrieNode
{
$char = $this->normalizeChar($char);
return $this->children[$char] ?? null;
}

/**
* Normalize the character to lowercase.
*/
private function normalizeChar(string $char): string
{
return strtolower($char);
}
}
161 changes: 159 additions & 2 deletions tests/DataStructures/TrieTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?php

/*
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #162
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request #162 and #172
* https://github.com/TheAlgorithms/PHP/pull/162
* https://github.com/TheAlgorithms/PHP/pull/172
*
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
* Thank you!
Expand All @@ -14,6 +15,7 @@
require_once __DIR__ . '/../../DataStructures/Trie/TrieNode.php';

use DataStructures\Trie\Trie;
use DataStructures\Trie\TrieNode;
use PHPUnit\Framework\TestCase;

class TrieTest extends TestCase
Expand All @@ -25,6 +27,9 @@ protected function setUp(): void
$this->trie = new Trie();
}

/**
* Test insertion and search functionality of the Trie.
*/
public function testInsertAndSearch()
{
$this->trie->insert('the');
Expand All @@ -42,6 +47,48 @@ public function testInsertAndSearch()
);
}

/**
* Test insertion and search functionality with mixed case words.
*/
public function testInsertAndSearchMixedCase()
{
$this->trie->insert('Apple');
$this->trie->insert('aPPle');
$this->assertTrue($this->trie->search('apple'), 'Expected "apple" to be found in the Trie.');
$this->assertTrue($this->trie->search('APPLE'), 'Expected "APPLE" to be found in the Trie.');
}

/**
* Test insertion and search functionality with special characters.
*/
public function testInsertAndSearchWithSpecialCharacters()
{
$this->trie->insert('hello123');
$this->trie->insert('[email protected]');
$this->assertTrue($this->trie->search('hello123'), 'Expected "hello123" to be found in the Trie.');
$this->assertTrue(
$this->trie->search('[email protected]'),
'Expected "[email protected]" to be found in the Trie.'
);
$this->assertTrue(
$this->trie->search('HELLO123'),
'Expected "HELLO123" not to be found in the Trie (case-sensitive).'
);
}

/**
* Test insertion and search functionality with long strings.
*/
public function testInsertAndSearchLongStrings()
{
$longString = str_repeat('a', 1000);
$this->trie->insert($longString);
$this->assertTrue($this->trie->search($longString), 'Expected the long string to be found in the Trie.');
}

/**
* Test the startsWith functionality of the Trie.
*/
public function testStartsWith()
{
$this->trie->insert('hello');
Expand All @@ -58,9 +105,31 @@ public function testStartsWith()
);
}

/**
* Test startsWith functionality with mixed case prefixes.
*/
public function testStartsWithMixedCase()
{
$this->trie->insert('PrefixMatch');
$this->trie->insert('PreFixTesting');
$this->assertEquals(
['prefixmatch', 'prefixtesting'],
$this->trie->startsWith('prefix'),
'Expected words starting with "prefix" to be found in the Trie (case-insensitive).'
);

$this->assertEquals(
['prefixmatch', 'prefixtesting'],
$this->trie->startsWith('PREFIX'),
'Expected words starting with "PREFIX" to be found in the Trie (case-insensitive).'
);
}

/**
* Test deletion of existing words from the Trie.
*/
public function testDelete()
{
// Insert words into the Trie
$this->trie->insert('the');
$this->trie->insert('universe');
$this->trie->insert('is');
Expand All @@ -80,12 +149,51 @@ public function testDelete()
$this->assertTrue($this->trie->search('rather'), 'Expected "rather" to be found.');
}

/**
* Test deletion of mixed case words from the Trie.
*/
public function testDeleteMixedCase()
{
$this->trie->insert('MixedCase');
$this->assertTrue($this->trie->search('mixedcase'), 'Expected "mixedcase" to be found before deletion.');

$this->trie->delete('MIXEDCASE');
$this->assertFalse(
$this->trie->search('MixedCase'),
'Expected "MixedCase" not to be found after deletion (case-insensitive).'
);
}

/**
* Test deletion of words with special characters.
*/
public function testDeleteWithSpecialCharacters()
{
$this->trie->insert('spec!@l#chars');
$this->assertTrue(
$this->trie->search('spec!@l#chars'),
'Expected "spec!@l#chars" to be found before deletion.'
);

$this->trie->delete('SPEC!@L#CHARS');
$this->assertFalse(
$this->trie->search('spec!@l#chars'),
'Expected "spec!@l#chars" not to be found after deletion.'
);
}

/**
* Test deletion of a non-existent word from the Trie.
*/
public function testDeleteNonExistentWord()
{
$this->trie->delete('nonexistent');
$this->assertFalse($this->trie->search('nonexistent'), 'Expected "nonexistent" to not be found.');
}

/**
* Test traversal of the Trie and retrieval of words.
*/
public function testTraverseTrieNode()
{
$this->trie->insert('hello');
Expand All @@ -99,11 +207,17 @@ public function testTraverseTrieNode()
$this->assertCount(3, $words, 'Expected 3 words in the Trie.');
}

/**
* Test behavior of an empty Trie.
*/
public function testEmptyTrie()
{
$this->assertEquals([], $this->trie->getWords(), 'Expected an empty Trie to return an empty array.');
}

/**
* Test retrieval of words from the Trie.
*/
public function testGetWords()
{
$this->trie->insert('apple');
Expand All @@ -117,19 +231,28 @@ public function testGetWords()
$this->assertCount(3, $words, 'Expected 3 words in the Trie.');
}

/**
* Test insertion of an empty string into the Trie.
*/
public function testInsertEmptyString()
{
$this->trie->insert('');
$this->assertTrue($this->trie->search(''), 'Expected empty string to be found in the Trie.');
}

/**
* Test deletion of an empty string from the Trie.
*/
public function testDeleteEmptyString()
{
$this->trie->insert('');
$this->trie->delete('');
$this->assertFalse($this->trie->search(''), 'Expected empty string not to be found after deletion.');
}

/**
* Test the startsWith functionality with a common prefix.
*/
public function testStartsWithWithCommonPrefix()
{
$this->trie->insert('trie');
Expand All @@ -142,4 +265,38 @@ public function testStartsWithWithCommonPrefix()
$this->assertContains('trier', $words, 'Expected "trier" to be found with prefix "tri".');
$this->assertCount(3, $words, 'Expected 3 words with prefix "tri".');
}

/**
* Test retrieval of the root node of the Trie.
*/
public function testGetRoot()
{
$root = $this->trie->getRoot();
$this->assertInstanceOf(TrieNode::class, $root, 'Expected root to be an instance of TrieNode.');
$this->assertFalse($root->isEndOfWord, 'Expected the root node not to be the end of a word.');
$this->assertCount(0, $root->children, 'Expected the root node to have no children initially.');
}

/**
* Test retrieval of the root node after populating the Trie with words.
*/
public function testGetRootAfterPopulation()
{
$this->trie->insert('TheAlgorithms');
$this->trie->insert('PHP');
$this->trie->insert('DSA');

$root = $this->trie->getRoot();

$this->assertInstanceOf(TrieNode::class, $root, 'Expected root to be an instance of TrieNode.');

// Assert that the root node is not marked as the end of a word
$this->assertFalse($root->isEndOfWord, 'Expected the root node not to be the end of a word.');

// Assert that the root node has children corresponding to the inserted words
$this->assertCount(3, $root->children, 'Expected the root node to have 3 children after inserting words.');
$this->assertTrue($root->hasChild('t'), 'Expected root to have a child for "t".');
$this->assertTrue($root->hasChild('p'), 'Expected root to have a child for "p".');
$this->assertTrue($root->hasChild('D'), 'Expected root to have a child for "D".');
}
}
Loading