A hardware shop labels its stock with short codes; several items may share a code. Staff often
search by both ends of a code: "starts with bo and ends with lt". Design Catalogue:
Catalogue()starts empty.add(code)stocks one more item with this code (returnsNone).remove(code)removes one item with this code and returnsTrue, or returnsFalseif no item has it.count(start, end)returns how many items currently in stock have a code that begins withstartand ends withend. Either string may be empty (it then matches everything), and the two may overlap inside the code:"bolt"matchesstart = "bol",end = "olt".
Examples
ops: ["Catalogue", "add", "add", "add", "add", "count", "count", "count", "remove", "count", "remove", "count"]
args: [[], ["bolt"], ["boot"], ["bolt"], ["belt"], ["bo", "t"], ["b", "lt"], ["bolt", "bolt"], ["bolt"], ["", "lt"], ["nut"], ["bol", "olt"]]
Output: [None, None, None, None, None, 3, 3, 2, True, 2, False, 1]
Explanation: "bo...t" matches bolt, boot, bolt. "b...lt" matches bolt, bolt, belt.
After one bolt is removed, bolt and belt end with "lt".
Constraints
- Codes,
startandendhave length0 .. 10and use lowercase letters - Up to
2 * 10**4calls in total - Target:
countmust not look at every stocked item; aboutO(L**2)peraddorremoveandO(L)percountis fine, whereLis the code length
Goals
- Answer a two-sided (start and end) filter with one walk down a trie
- Insert every suffix of a word glued to the whole word so both ends become one path
- Keep counts so that duplicates and removals stay correct