Java で回文をチェックする

JavaBeginner
オンラインで実践に進む

はじめに

この実験では、Java で文字列を回文かどうかをチェックする方法を学びます。回文とは、前向きと後ろ向きで同じように読める文字列です。

2 つのポインタを使って回文をチェックする

最初に実装する方法は、2 つのポインタアプローチです。文字列を入力として受け取り、その文字列が回文かどうかを示すブール値を返す isPalindrome というメソッドを作成します。

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        int start = 0;
        int end = str.length() - 1;

        while (start < end) {
            char startChar = Character.toLowerCase(str.charAt(start));
            char endChar = Character.toLowerCase(str.charAt(end));

            if (startChar!= endChar) {
                return false;
            }

            start++;
            end--;
        }

        return true;
    }
}

isPalindrome メソッドは、それぞれ文字列の先頭と末尾から始まる 2 つのポインタ startend を使用します。2 つのポインタが真ん中で出会うまで、ループが実行されます。

各反復では、startend のポインタにある文字を比較します。それらが等しくなければ、false を返します。等しければ、ポインタを更新して、文字列の次の文字セットをチェックします。

このメソッドをテストするには、main メソッドを追加して、さまざまな入力文字列で isPalindrome メソッドを呼び出せます。

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        // isPalindrome メソッドの実装
    }

    public static void main(String[] args) {
        System.out.println("Is 'racecar' a palindrome? " + isPalindrome("racecar"));
        System.out.println("Is 'hello' a palindrome? " + isPalindrome("hello"));
    }
}

再帰を使って回文をチェックする

次に実装する方法は、再帰アプローチです。文字列を入力として受け取り、開始インデックスと終了インデックスを入力として受け取る isPalindromeRecursive と呼ばれる新しいメソッドを作成します。

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        String lowercaseStr = str.toLowerCase();
        return isPalindromeRecursive(lowercaseStr, 0, lowercaseStr.length() - 1);
    }

    public static boolean isPalindromeRecursive(String str, int start, int end) {
        if(start >= end) {
            return true;
        }

        char startChar = Character.toLowerCase(str.charAt(start));
        char endChar = Character.toLowerCase(str.charAt(end));

        if(startChar!= endChar) {
            return false;
        }

        return isPalindromeRecursive(str, start + 1, end - 1);
    }

    public static void main(String[] args) {
        // isPalindrome と isPalindromeRecursive メソッドのテスト
    }
}

isPalindromeRecursive メソッドは、再帰を使って文字列を回文かどうかをチェックします。2 つの基本ケースがあります。

  1. start インデックスが end インデックス以上の場合、文字列内のすべての文字をチェックして一致することがわかったことを意味するので、true を返します。
  2. startend のインデックスにある文字が等しくない場合、false を返します。

どちらの基本ケースも満たされない場合、更新されたインデックスで再度 isPalindromeRecursive を呼び出します。

これで、main メソッド内で再帰メソッドを呼び出すことでテストできます。

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        // isPalindrome メソッドの実装
    }

    public static boolean isPalindromeRecursive(String str, int start, int end) {
        // isPalindromeRecursive メソッドの実装
    }

    public static void main(String[] args) {
        System.out.println("Is 'racecar' a palindrome? " + isPalindromeRecursive("racecar", 0, 6));
        System.out.println("Is 'hello' a palindrome? " + isPalindromeRecursive("hello", 0, 4));
    }
}

回文をチェックするための文字列を逆にする

最後に実装する方法は、文字列を逆にするアプローチです。文字列を入力として受け取る isPalindromeReverse と呼ばれる新しいメソッドを作成します。

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        // isPalindrome メソッドの実装
    }

    public static boolean isPalindromeRecursive(String str, int start, int end) {
        // isPalindromeRecursive メソッドの実装
    }

    public static boolean isPalindromeReverse(String str) {
        String reversed = "";

        for (int i = str.length() - 1; i >= 0; i--) {
            reversed += str.charAt(i);
        }

        return str.equalsIgnoreCase(reversed);
    }

    public static void main(String[] args) {
        // isPalindrome と isPalindromeRecursive メソッドのテスト
        System.out.println("Is 'racecar' a palindrome? " + isPalindromeReverse("racecar"));
        System.out.println("Is 'hello' a palindrome? " + isPalindromeReverse("hello"));
    }
}

isPalindromeReverse メソッドは、reversed と呼ばれる新しい文字列を作成し、入力文字列の末尾から先頭に向かって反復することでそれを埋めます。その後、大文字と小文字を区別せずに 2 つの文字列が等しい場合に true を返します。

main メソッドに isPalindromeReverse への呼び出しを追加することで、このメソッドをテストできます。

Java Streams を使って回文をチェックする

最後に、Java Streams API を使って回文をチェックします。文字列を入力として受け取る isPalindromeStream と呼ばれる新しいメソッドを作成します。

import java.util.stream.IntStream;

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        // isPalindrome メソッドの実装
    }

    public static boolean isPalindromeRecursive(String str, int start, int end) {
        // isPalindromeRecursive メソッドの実装
    }

    public static boolean isPalindromeReverse(String str) {
        // isPalindromeReverse メソッドの実装
    }

    public static boolean isPalindromeStream(String str) {
        String lowercaseStr = str.toLowerCase();

        return IntStream.range(0, lowercaseStr.length() / 2)
             .noneMatch(i -> lowercaseStr.charAt(i)!= lowercaseStr.charAt(lowercaseStr.length() - i - 1));
    }

    public static void main(String[] args) {
        // isPalindrome と isPalindromeRecursive メソッドのテスト
        System.out.println("Is 'racecar' a palindrome? " + isPalindromeStream("racecar"));
        System.out.println("Is 'hello' a palindrome? " + isPalindromeStream("hello"));
    }
}

isPalindromeStream メソッドは、IntStream クラスを使ってインデックスの範囲を生成し、それを使って文字列内の文字を比較します。

文字列の長さを n、インデックスを i としたとき、ithn-i-1th の文字が等しいという条件に違反する文字がなければ true を返すように noneMatch メソッドを使っています。

main メソッドに isPalindromeStream への呼び出しを追加することで、このメソッドをテストできます。

まとめ

この実験では、Java で与えられた文字列が回文かどうかをチェックする方法を学びました。このタスクを達成するために 4 つの異なる方法を実装しました。

  1. 2 つのポインタアプローチ
  2. 再帰アプローチ
  3. 文字列を逆にするアプローチ
  4. Java Streams アプローチ

これらの方法を理解したので、より複雑な問題を解決するために使うことができます!