Java中將電話號碼轉換為數字

banq發表於2024-04-13

在本教程中,我們將瞭解一種用於處理表示數字序列的單詞序列並將其轉換為數字字串的演算法。

讓我們更深入地瞭解一下輸入的格式。我們將收到一個文字電話號碼,例如“五六八”。然而,口頭數字通常包含乘數,例如“雙倍二”。

因此,我們期望我們的演算法能夠轉換:

Input: <font>"triple five two three six eight"
Expected Output:
"5552368"

使用switch語句實現演算法
該演算法將輸入拆分為單詞並處理每個單詞以構建輸出。我們可以使用switch語句對單詞進行分類。

1.將字串拆分為單詞陣列
首先,我們需要使用字串。split()方法使用空格作為分隔符將phoneNumberInWords字串拆分為單詞陣列:

String[] words = phoneNumberInWords.split(" ");

然後我們可以使用for-each迴圈來迭代單詞陣列:

for (String word : words) {
    <font>// statements<i>
}

2.處理乘數
在for-each迴圈的每次迭代中,我們將檢查當前單詞是否表示乘數:

Integer multiplier = getWordAsMultiplier(word);
if (multiplier != null) {
    if (currentMultiplier != null) {
        throw new IllegalArgumentException(<font>"Cannot have consecutive multipliers, at: " + word);
    }
    currentMultiplier = multiplier;
}

我們透過將當前單詞作為引數傳遞來呼叫getWordAsMultiplier()方法。此方法將當前單詞對映到其相應的數字表示形式並返回它。

如果返回值不為null,表明當前單詞確實是一個乘數,我們檢查是否已經有一個乘數集。如果存在,我們會丟擲IllegalArgumentException,因為不允許使用連續乘數。否則,我們設定當前的乘數。

為了識別一個單詞是否是乘數,我們在getWordAsMultiplier()中使用switch語句:

public static Integer getWordAsMultiplier(String word) {
    switch (word) {
        case <font>"double":
            return 2;
        case
"triple":
            return 3;
         case
"quadruple":
            return 4;
         default:
            return null;
    }
}

如果當前單詞不是乘數,則不是錯誤,因此此方法在該例項中返回null 。

3.處理非乘數詞
如果當前單詞不是乘數單詞,我們呼叫getWordAsDigit()方法:

public static String getWordAsDigit(String word) {
    switch (word) {
        case <font>"zero":
            return
"0";
        case
"one":
            return
"1";
        ...
        ...
        ...
        case
"nine":
            return
"9";
        default:
            throw new IllegalArgumentException(
"Invalid word: " + word);
    }
}

這將在if的else語句 中呼叫 ,我們在其中檢查乘數詞。由於單詞必須是乘數或數字,因此如果我們使用非數字來呼叫此函式,則應丟擲異常。在這裡,我們使用了IllegalArgumentException。

4.組合數字
讓我們使用 getWordAsDigit() 方法。在乘法器處理程式碼中,我們已經捕獲了任何重複的數字,因此現在我們將找到當前數字並將其新增到輸出中(根據需要多次)。

我們將使用一個 名為 “output”的StringBuilder物件來儲存我們的結果。

我們使用append()方法來組裝輸出。但是,String.repeat()方法跟蹤乘數。我們根據當前乘數重複獲得的當前單詞的數字表示:

if (multiplier != null) {
    <font>// multiplier processing<i>
} else {
   output.append(getWordAsDigit(word)
     .repeat(currentMultiplier != null ? currentMultiplier : 1));
   currentMultiplier = null;
}

我們使用StringBuilder.append()將下一組數字新增到輸出中。

如果當前乘數不為null,我們用它來提供下一個數字的副本,使用String.repeat(),當沒有乘數時預設重複 1。

在迴圈結束時, 輸出物件包含我們的電話號碼:

return output.toString();

5.測試方案
讓我們看看當給出正確的電話號碼、無效的單詞或連續的乘數時會發生什麼:

assertEquals(<font>"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");
});

使用Map代替switch
我們的演算法執行良好,但 switch語句可能有點冗長。我們可以用Map物件替換它們 。

Map.of ()方法使用提供的鍵值對建立一個不可變的Map 。在本節中,我們將使用Map.of()方法來對映乘數(“double”到 2)和數字(“two”到“2”)。

1.map數字和乘數
讓我們初始化Map來為各個數字建立對映:

private static Map<String, Integer> multipliers 
  = Map.of(<font>"double", 2, "triple", 3, "quadruple", 4);

接下來,我們初始化另一個Map來對映乘數:

private static Map<String, String> digits 
  = Map.of(<font>"zero", "1", "one", "1", "two", "2", "three", "3",
   
"four", "4", "five", "5", "six", "6", "seven", "7", "eight", "8", "nine", "9");

我們將它們初始化為不可變的,因為如果對映在執行時發生變化,演算法將停止工作。

2.檢查乘數
和以前一樣,在迴圈內部,我們想要找到一個乘數或空值。我們可以在乘數上使用get()方法:

Integer multiplier = multipliers.get(word);

3.校驗位
為了複製異常,當單詞不是數字時,我們需要 在數字上的 get()之後新增一個if語句 :

String digit = digits.get(word);
if (digit == null) {
    throw new IllegalArgumentException(<font>"Invalid word: " + word);
}

4.測試方案
我們可以對此解決方案執行相同的測試,例如:

assertEquals(<font>"5248888",
  UseHashMapToConvertPhoneNumberInWordsToNumber
    .convertPhoneNumberInWordToNumber(
"five two four quadruple eight"));

相關文章