在 Java 中,迴文數是指由前往後、由後往前讀取數字皆相同的整數——121、1331 和 12321 都是教科書上的範例,你可以透過算術反轉 int,或是將其轉換為 String 並呼叫 StringBuilder.reverse() 來偵測它們。對於大多數的正式環境程式碼,String 方式最短,但整數算術版本可避免任何字串配置,並能自然處理數值邊緣情況,例如前置零。兩種方法對於純數字輸入都能得到正確答案,但對於以詞組、變音符號字母或標點符號定義迴文規則的競賽或謎題,兩者都可能會悄悄地產生不一致的結果。一個透明的瀏覽器內檢查工具可以解決這個落差:它會顯示它所使用的精確正規化比較字串,讓你能確認你的 Java 邏輯在相同規則下產生相同的判定。如果你的 Java 方法對 12321 傳回 true,但檢查工具傳回 no,差異幾乎總是在於各實作在比較前移除了什麼——標點符號、大小寫或 Unicode 字母——而檢查工具的預覽能讓你一眼看出這項差異。

how to check palindrome number in java
用 Java 檢查迴文數並驗證輸出

用 Java 檢查迴文數的方法

值得牢記的兩種 Java 模式是整數算術與字串反轉。算術版本會對任何負數立即傳回 false,接著使用餘數和除法反轉剩餘的數字。字串版本雖然較短,但每次呼叫會配置兩個字串。

整數算術反轉:

public static boolean isPalindromeNumber(int x) {   if (x < 0) return false;   int original = x;   int reversed = 0;   while (x > 0) {     reversed = reversed * 10 + x % 10;     x /= 10;   }   return original == reversed; }

逐步檢視 12321:迴圈依序取出 1、2、3、2、1,並建構出 reversed = 12321,等於原值,因此檢查結果為 true。對於 123,reversed 變成 321,兩值不同,方法傳回 false。

適用任何字元序列的字串反轉:

public static boolean isPalindrome(String s) {   String clean = s.replaceAll("[^A-Za-z0-9]", "").toLowerCase();   return clean.equals(new StringBuilder(clean).reverse().toString()); }

該正規表示式會移除所有非英數字元並統一大小寫,因此 "Race car" 會變成 "racecar" 並與其反轉結果相符。如果你想更深入了解移除標點的正規表示式,這份 用 Java 從字串中移除標點 指南會逐步介紹更安全的替代方案,在保留 Unicode 字母的同時,而不是將它們默默刪除。

使用迴文檢查工具驗證邏輯

當你的 Java 方法編譯完成後,要確認它符合已記錄規則的最快方法,就是將相同的輸入執行於 迴文檢查工具,並閱讀它顯示的正規化比較字串。這個工具完全在瀏覽器中運作,因此測試輸入絕不會離開該頁面。

  1. 在輸入欄位中輸入你想測試的單字、片語、句子或數字。
  2. 執行檢查工具,並檢查預覽面板中顯示的正規化英數字串。
  3. 閱讀判定結果以及並列顯示的保留字元計數。
  4. 將所述的正規化規則(不區分大小寫、保留 Unicode 字母和數字、套用 NFKC、忽略標點與表情符號)與你的 Java 程式碼所要滿足的任何特定競賽規則進行比對。
  5. 如果判定結果與你的 Java 輸出不一致,請查看預覽字串,精準找出哪個字元在比較前被過濾或轉換。

對於像 12321 這樣的純數字,預覽應原樣顯示數字,判定結果應為 yes。對於 "A man, a plan, a canal: Panama",預覽會合併為 amanaplanacanalpanama 並傳回 yes,符合 Merriam-Webster 所記錄的經典詞組範例。對於 "Hello",預覽為 hello,判定結果為 no。

值得測試的 Java 迴文邊緣情況

大多數 Java 迴文錯誤會出現在原作者從未設想過的輸入上。將下列各項同時透過你的程式碼和檢查工具執行,就能迅速暴露出規則上的落差。

  • 負數。依一般慣例,-121 並非迴文,因為前導負號破壞了對稱性。上方的整數方法透過提前 return 來處理這種情況;而字串方法在移除非英數的負號後,會將 "-121" 視為 "121",並錯誤地回報 true。
  • 前置零。"010" 作為字串時仍保持對稱,但解析為整數時會變成 10。若你使用 Integer.parseInt 解析 "010",將會失去前置零;若你將值保留為字串,則對稱測試會通過。
  • Unicode 字母。"Été" 在檢查工具的公開規則下會正規化為 été,是個迴文。僅限於 [A-Za-z0-9] 的 Java 正規表示式會移除變音字母,僅留下 t,使得 Java 程式碼最終是在比較一個保留下來的單一字母與其本身,而非原始詞組。
  • 混合文字與表情符號。表情符號不在檢查工具的英數範圍內,會在比較時被排除,因此 "abc😀cba" 會正規化為 "abccba" 並傳回 yes。如果你的 Java 程式碼宣稱套用相同規則,就應該對應這個範圍。
  • 僅含標點的輸入。"!!!"、純空白字串,以及空輸入,由於在正規化後沒有任何字母或數字存活下來,因此都會從檢查工具收到錯誤。如果一個 Java 方法先移除所有內容,再比較兩個空字串,就會錯誤地將這些判定為迴文。

主要 Java 方法的比較

每一種 Java 迴文模式都有不同的權衡取捨。下表概述了它們各自的優勢,協助你為程式碼選擇正確的切入點。

方法最佳用途是否配置字串?是否保留 Unicode 字母?
整數算術反轉純正數、熱路徑否不適用(僅限數字)
StringBuilder.reverse() 搭配已清理的 String簡短的混合輸入、可讀性高的程式碼是(兩個 String)僅在正規表示式包含它們時
字元陣列雙指標走訪對記憶體敏感的程式碼、無配置否僅在判斷式包含它們時
IntStream / 函數式管線表達力強的單行式、平行風格是(已裝箱的字元)僅在過濾器包含它們時

對於一個明確命名為 isPalindromeNumber 的方法來說,整數算術版本是最安全的預設選擇。任何混合字母、變音符號或標點的內容,則應交由字串型方法處理,並在 docstring 中明確聲明其正規化規則。

當檢查工具的判定與你的 Java 輸出不同時

不一致是一項資訊,而非錯誤。它幾乎總是指向以下三項規則差異之一:大小寫處理、保留的字元集,或正規化形式。檢查工具明確地以固定的英文語系進行小寫轉換、套用 Unicode NFKC 正規化,並僅保留 Unicode 字母或數字碼位,同時忽略空白、標點、符號與表情符號。如果你的 Java 正規表示式是 [A-Za-z0-9],它只會匹配檢查工具所保留內容的子集——僅限 ASCII 字母與數字——因此對於 "Été" 會產生不一致,因為 É 會在比較前被移除。

如果某個特定的挑戰題或面試題目將迴文定義為嚴格的逐字元相等,請遵循該定義,而非檢查工具的預設值。此工具刻意公開其正規化預覽,正是為了讓規則可供稽核;你可以透過呼叫 Normalizer.normalize(input, Normalizer.Form.NFKC)、過濾掉 Character.getType 傳回值既不是 LETTER 也不是 NUMBER 的字元、以 Locale.ROOT 進行小寫轉換,並將結果與其反轉結果進行比較,在 Java 中重現相同的比較。

對於最多達一百萬個 Unicode 碼位的任何輸入,該比較會在瀏覽器中本地執行,無需帳號或上傳,因此能快速反覆測試邊緣情況。將此檢查工具視為其自身規則下的確定性仲裁者,而非通用判官——只要你的 Java 實作與之共用相同的公開正規化,就會與之對齊。

如需更深入的探討,請參閱 如何用 Python 檢查迴文數:3 種方法。