Problem · String

Whole-Word Pronunciation Annotations

Learn this problem
MediumHeyGen logoHeyGenFULLTIMEPHONE SCREEN

Problem statement

You are given a Unicode string text and an ordered two-column array glossary. Each row is [phrase, pronunciation].

Scan text from left to right. Whenever one or more glossary phrases match case-insensitively at the current position as a whole word or whole phrase, choose the phrase with the most Unicode code points. If equal-length phrases match, choose the earlier glossary row.

Replace the chosen occurrence with <pron pron="pronunciation">original text</pron>, preserving the exact casing and spacing of the matched text. Continue after that occurrence, so annotations never overlap or nest. Characters that do not begin a selected match remain unchanged.

A match is whole-word bounded when the character immediately before it, if any, and the character immediately after it, if any, are not Unicode letters or digits. Case-insensitive comparison uses Unicode lowercase equivalence; test data does not require multi-code-point folds such as ß matching ss.

Function

annotatePronunciations(text: String, glossary: String[][]) → String

Examples

Example 1

text = "Read lead and LEAD."glossary = [["lead","leed"]]return = "Read <pron pron=\"leed\">lead</pron> and <pron pron=\"leed\">LEAD</pron>."

Both whole-word matches are annotated, and each replacement preserves the casing from the input text.

Example 2

text = "New York and York"glossary = [["York","york"],["New York","new-york"]]return = "<pron pron=\"new-york\">New York</pron> and <pron pron=\"york\">York</pron>"

At the first position, the two-word phrase wins over the shorter suffix. The later standalone word is then annotated separately.

Example 3

text = "CAT scat cat2 cat!"glossary = [["cat","kat"]]return = "<pron pron=\"kat\">CAT</pron> scat cat2 <pron pron=\"kat\">cat</pron>!"

The match is case-insensitive, but the substring inside another word and the substring followed by a digit are not whole words.

Constraints

  • 1 <= text.length <= 5000 Unicode code points.
  • 1 <= glossary.length <= 100.
  • Each glossary row contains exactly two nonempty strings: a phrase and its pronunciation.
  • Every phrase begins and ends with a Unicode letter or digit and contains at most 100 Unicode code points.
  • No two phrases are equal under the exercise's case-insensitive comparison.
  • The input text, phrases, and pronunciations do not contain <, >, &, or a double quote, so the requested markup needs no additional escaping.
  • Pronunciations contain only letters, digits, spaces, apostrophes, periods, slashes, and hyphens.
drafts saved locally
public String annotatePronunciations(String text, String[][] glossary) {
    // Write your code here.
}
text"Read lead and LEAD."
glossary[["lead","leed"]]
expected"Read <pron pron=\"leed\">lead</pron> and <pron pron=\"leed\">LEAD</pron>."
checking account