1. Overview
We may wish to process a telephone number expressed as text. Perhaps we have received a telephone number via a speech-to-text interface.
2. Introduction to Problem Statement
So, we expect our algorithm to convert:
Input: "triple five two three six eight"
Expected Output: "5552368"
3. Implementing the Algorithm with switch Statements
switch statements.
First, we need to use the String.split() method to split the phoneNumberInWords
String[] words = phoneNumberInWords.split(" ");
We can then use a loop to iterate over the words
for (String word : words) {
// statements
}
In each iteration of the for-each
Integer multiplier = getWordAsMultiplier(word);
if (multiplier != null) {
if (currentMultiplier != null) {
throw new IllegalArgumentException("Cannot have consecutive multipliers, at: " + word);
}
currentMultiplier = multiplier;
}
getWordAsMultiplier() method by passing the current word as an argument. This method maps the current word to its corresponding numerical representation and returns it.
If the returned value is not null, indicating the current word is indeed a multiplier, we check if there is already a multiplier set. If there is, we throw an IllegalArgumentException because consecutive multipliers are not allowed. Otherwise, we set the current multiplier.
public static Integer getWordAsMultiplier(String word) {
switch (word) {
case "double":
return 2;
case "triple":
return 3;
case "quadruple":
return 4;
default:
return null;
}
}
It’s not an error if the current word isn’t a multiplier, so this method returns null in that instance.
3.3. Handle Non-multiplier Word
If the current word isn’t a multiplier word, we call the getWordAsDigit() method:
public static String getWordAsDigit(String word) {
switch (word) {
case "zero":
return "0";
case "one":
return "1";
...
...
...
case "nine":
return "9";
default:
throw new IllegalArgumentException("Invalid word: " + word);
}
}
This will be called in the else statement of the if where we check for a multiplier word. As a word must be either a multiplier or a digit, this function should throw an exception if we call it with a non-digit number. Here, we’ve used IllegalArgumentException.
Let’s use the getWordAsDigit() method. In the multiplier processing code, we’ve captured any duplication of digits, so now we’re going to find the current digit and add it to the output as many times as necessary.
We’ll use a StringBuilder object called output to store our results.
We use the append() method to assemble the output. However, the method tracks the multiplier. We repeat the obtained digit representation of the current word based on the current multiplier
if (multiplier != null) {
// multiplier processing
} else {
output.append(getWordAsDigit(word)
.repeat(currentMultiplier != null ? currentMultiplier : 1));
currentMultiplier = null;
}
null, we use it to provide copies of the next digit, using
At the end of the loop, the output object contains our phone number:
return output.toString();
Let’s see what happens when a correct phone number, invalid word, or consecutive multipliers are given:
assertEquals("5248888",
UseSwitchToConvertPhoneNumberInWordToNumber
.convertPhoneNumberInWordToNumber("five two four quadruple eight"));
assertThrows(IllegalArgumentException.class, () -> {
UseSwitchToConvertPhoneNumberInWordToNumber
.convertPhoneNumberInWordToNumber("five eight invalid two four null eight");
});
assertThrows(IllegalArgumentException.class, () -> {
UseSwitchToConvertPhoneNumberInWordToNumber
.convertPhoneNumberInWordToNumber("five eight three double triple");
});
4. Using Map Instead of switch
Our algorithm works well, but switch statements can be a little long-winded. We can replace them with Map objects.
The method creates an immutable Map with the provided key-value pairs. In this section, we’ll use the Map.of() method to map multipliers (“double” to 2) and digits (“two” to “2”).
4.1. Map Digits and Multipliers
Let’s initialize the Map
private static Map<String, Integer> multipliers
= Map.of("double", 2, "triple", 3, "quadruple", 4);
Map
private static Map<String, String> digits
= Map.of("zero", "1", "one", "1", "two", "2", "three", "3",
"four", "4", "five", "5", "six", "6", "seven", "7", "eight", "8", "nine", "9");
We initialize them as immutable because the algorithm would stop working if the Map could change at runtime.
As before, inside the loop, we want to find a multiplier or null. We can use the get() method on multipliers
Integer multiplier = multipliers.get(word);
To replicate the exception, when a word is not a digit, we need an additional if statement after the get() on digits:
String digit = digits.get(word);
if (digit == null) {
throw new IllegalArgumentException("Invalid word: " + word);
}
We can run the same tests on this solution, such as:
assertEquals("5248888",
UseHashMapToConvertPhoneNumberInWordsToNumber
.convertPhoneNumberInWordToNumber("five two four quadruple eight"));
5. Conclusion
In this article, we looked at an algorithm for processing telephone numbers.
We implemented the basic algorithm using switch statements. Then, we optimized the implementation using Java Map.
As always, the example code is over on GitHub