Tries are pretty effective for implementing maps where keys are short strings. The Wikipedia article explains this pretty well.
To deal with duplicates, just make each node of the tree a repository of a linked list of duplicate matches
Here is the basic structure for trie
struct Trie {
struct Trie* letter;
struct List *matches;
};
malloc (26 * sizeof (struct Trie)) , . , .
, , , struct List .