Palindrome Algorithm และการทดสอบ JUnit 5

Aug 27 2020

ฉันมีคลาส "Palindrome" ที่มีฟังก์ชันบางอย่างสำหรับตรวจสอบว่าบางสิ่งเป็น Palindromes หรือไม่ สำหรับการตรวจสอบฉันมี 2 อัลกอริทึมที่แตกต่างกันอันหนึ่งเป็นแบบวนซ้ำและอีกอันที่ทำซ้ำ

ฉันพอใจกับอัลกอริทึม แต่ฉันไม่แน่ใจว่าวิธีที่ฉันทำโอเวอร์โหลดและในที่สุดก็แยกวิเคราะห์ทุกอย่างไปยังฟังก์ชัน check charArray เป็นสิ่งที่ชาญฉลาด

ฉันยังมีการทดสอบ Junit 5 ที่พิสูจน์ว่าทุกอย่างใช้งานได้ ที่นี่ฉันไม่แน่ใจว่ารหัสที่ดีกับหลายรังและวิธีการ / การทดสอบที่ฉันเลือกหรือไม่และถ้ามีรหัสซ้ำกันมากสำหรับอัลกอริทึมการทำซ้ำและการเรียกซ้ำเป็นสิ่งที่ดี ขอบคุณล่วงหน้า.

คลาส Palindrome

package com.gr;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Lucifer Uchiha
 * @version 1.0
 */
public class Palindrome {

    /* Iterative */

    /**
     * Returns a boolean of whether the char array is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param chars char array containing the characters to be checked.
     * @return boolean of whether the char array is a palindrome or not.
     */
    public static boolean isCharArrayPalindromeIterative(char[] chars) {
        if (chars.length < 1)
            return false;
        char[] formattedChars = convertAllCharsToUpperCase(chars);
        boolean isPalindrome = true;
        for (int i = 0; i != formattedChars.length / 2; i++)
            if (formattedChars[i] != formattedChars[(formattedChars.length - 1) - i]) {
                isPalindrome = false;
                break;
            }
        return isPalindrome;
    }

    /**
     * Returns a boolean of whether the word of type String is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param word the word to be checked.
     * @return boolean of whether the word is a palindrome or not.
     */
    public static boolean isWordPalindromeIterative(String word) {
        return isCharArrayPalindromeIterative(word.toCharArray());
    }

    /**
     * Returns a boolean of whether the sentence of type String is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param sentence the sentence to be checked.
     * @return boolean of whether the sentence is a palindrome or not.
     */
    public static boolean isSentencePalindromeIterative(String sentence) {
        String newSentence = sentence.replaceAll("[^a-zA-Z]", "");
        return isWordPalindromeIterative(newSentence);
    }

    /**
     * Returns a boolean of whether the number of type byte (-128 to 127) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(byte number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type short (32,768 to 32,767) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(short number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type int (-2,147,483,648 to 2,147,483,647) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(int number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807) is a palindrome or not.
     * This is determined by using the iterative algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeIterative(long number) {
        return isWordPalindromeIterative(String.valueOf(number));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type long to end of type long.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Long> getAllNumberPalindromesInRangeIterative(long start, long end) {
        List<Long> results = new ArrayList<>();
        for (long number = start; number != end; number++)
            if (isNumberPalindromeIterative(number))
                results.add(number);
        return results;
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type int to end of type int.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Integer> getAllNumberPalindromesInRangeIterative(int start, int end) {
        return convertLongListToIntegerList(getAllNumberPalindromesInRangeIterative((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type short to end of type short.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Short> getAllNumberPalindromesInRangeIterative(short start, short end) {
        return convertLongListToShortList(getAllNumberPalindromesInRangeIterative((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type byte to end of type byte.
     * This is determined by using the iterative algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Byte> getAllNumberPalindromesInRangeIterative(byte start, byte end) {
        return convertLongListToByteList(getAllNumberPalindromesInRangeIterative((long) start, (long) end));
    }

    /* Recursive */

    /**
     * Returns a boolean of whether the char array is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param chars char array containing the characters to be checked.
     * @return boolean of whether the char array is a palindrome or not.
     */
    public static boolean isCharArrayPalindromeRecursive(char[] chars) {
        if (chars.length < 1)
            return false;
        char[] formattedChars = convertAllCharsToUpperCase(chars);
        return recursion(formattedChars, 0, formattedChars.length - 1);
    }

    /**
     * The recursive algorithm.
     *
     * @param chars char array containing the characters to be checked.
     * @param start the left char being compared.
     * @param end   the right char being compared.
     * @return boolean of whether the char array is a palindrome or not.
     */
    private static boolean recursion(char[] chars, int start, int end) {
        if (start == end)
            return true;
        if (chars[start] != chars[end])
            return false;
        if (start < end + 1)
            return recursion(chars, ++start, --end);
        return true;
    }

    /**
     * Returns a boolean of whether the word of type String is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param word the word to be checked.
     * @return boolean of whether the word is a palindrome or not.
     */
    public static boolean isWordPalindromeRecursive(String word) {
        return isCharArrayPalindromeRecursive(word.toCharArray());
    }

    /**
     * Returns a boolean of whether the sentence of type String is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param sentence the sentence to be checked.
     * @return boolean of whether the sentence is a palindrome or not.
     */
    public static boolean isSentencePalindromeRecursive(String sentence) {
        String newSentence = sentence.replaceAll("[^a-zA-Z]", "");
        return isWordPalindromeRecursive(newSentence);
    }

    /**
     * Returns a boolean of whether the number of type byte (-128 to 127) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(byte number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type short (32,768 to 32,767) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(short number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type int (-2,147,483,648 to 2,147,483,647) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(int number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a boolean of whether the number of type long (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807) is a palindrome or not.
     * This is determined by using the recursive algorithm.
     *
     * @param number the number to be checked.
     * @return boolean of whether the number is a palindrome or not.
     */
    public static boolean isNumberPalindromeRecursive(long number) {
        return isWordPalindromeRecursive(String.valueOf(number));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type long to end of type long.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Long> getAllNumberPalindromesInRangeRecursive(long start, long end) {
        List<Long> results = new ArrayList<>();
        for (long number = start; number != end; number++)
            if (isNumberPalindromeRecursive(number))
                results.add(number);
        return results;
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type int to end of type int.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Integer> getAllNumberPalindromesInRangeRecursive(int start, int end) {
        return convertLongListToIntegerList(getAllNumberPalindromesInRangeRecursive((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type short to end of type short.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Short> getAllNumberPalindromesInRangeRecursive(short start, short end) {
        return convertLongListToShortList(getAllNumberPalindromesInRangeRecursive((long) start, (long) end));
    }

    /**
     * Returns a List containing all the numbers that are palindromes in the range that is given from
     * start of type byte to end of type byte.
     * This is determined by using the recursive algorithm.
     *
     * @param start the start of the range, inclusive.
     * @param end   the end of the range, exclusive.
     * @return List containing all the numbers that are palindromes in the given range.
     */
    public static List<Byte> getAllNumberPalindromesInRangeRecursive(byte start, byte end) {
        return convertLongListToByteList(getAllNumberPalindromesInRangeRecursive((long) start, (long) end));
    }

    /**
     * Converts all letters in the given char array to capital letters if they aren't already.
     *
     * @param chars the start of the range, inclusive.
     * @return char array with the capitalized letters.
     */
    private static char[] convertAllCharsToUpperCase(char[] chars) {
        char[] formattedChars = new char[chars.length];
        for (int i = 0; i != chars.length; i++)
            if (Character.isLetter(chars[i]) && Character.isLowerCase(chars[i]))
                formattedChars[i] = Character.toUpperCase(chars[i]);
            else
                formattedChars[i] = chars[i];
        return formattedChars;
    }

    /**
     * Converts a List containing Long values to a List of Bytes.
     *
     * @param listOfLongs the List containing the Long values
     * @return the List containing the Byte values
     */
    private static List<Byte> convertLongListToByteList(List<Long> listOfLongs) {
        List<Byte> result = new ArrayList<>();
        for (Long i : listOfLongs)
            result.add(i.byteValue());
        return result;
    }

    /**
     * Converts a List containing Long values to a List of Shorts.
     *
     * @param listOfLongs the List containing the Long values
     * @return the List containing the Shorts values
     */
    private static List<Short> convertLongListToShortList(List<Long> listOfLongs) {
        List<Short> result = new ArrayList<>();
        for (Long i : listOfLongs)
            result.add(i.shortValue());
        return result;
    }

    /**
     * Converts a List containing Long values to a List of Integers.
     *
     * @param listOfLongs the List containing the Long values
     * @return the List containing the Integers values
     */
    private static List<Integer> convertLongListToIntegerList(List<Long> listOfLongs) {
        List<Integer> result = new ArrayList<>();
        for (Long i : listOfLongs)
            result.add(i.intValue());
        return result;
    }
}

คลาสทดสอบ Palindrome

package com.gr;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@DisplayName("Palindrome Class")
public class PalindromeTest {

    // Nested Iterative
    @Nested
    class Iterative {

        @Nested
        class Word {

            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isWordPalindromeIterative(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isWordPalindromeIterative("A"));
                assertTrue(Palindrome.isWordPalindromeIterative("a"));
            }

            @Test
            void testName() {
                assertTrue(Palindrome.isWordPalindromeIterative("ABBA"));
                assertTrue(Palindrome.isWordPalindromeIterative("Ava"));
                assertTrue(Palindrome.isWordPalindromeIterative("bob"));
                assertFalse(Palindrome.isWordPalindromeIterative("FAIL"));
                assertFalse(Palindrome.isWordPalindromeIterative("Fail"));
                assertFalse(Palindrome.isWordPalindromeIterative("fail"));
            }

            @Test
            void testWord() {
                assertTrue(Palindrome.isWordPalindromeIterative("madam"));
                assertTrue(Palindrome.isWordPalindromeIterative("Racecar"));
                assertTrue(Palindrome.isWordPalindromeIterative("RADAR"));
                assertFalse(Palindrome.isWordPalindromeIterative("FAIL"));
                assertFalse(Palindrome.isWordPalindromeIterative("Fail"));
                assertFalse(Palindrome.isWordPalindromeIterative("fail"));
            }
        }

        @Nested
        class Sentence {
            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isSentencePalindromeIterative(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isSentencePalindromeIterative("A"));
                assertTrue(Palindrome.isSentencePalindromeIterative("a"));
            }

            @Test
            void testSingleWord() {
                assertTrue(Palindrome.isSentencePalindromeIterative("madam"));
                assertTrue(Palindrome.isSentencePalindromeIterative("Racecar"));
                assertTrue(Palindrome.isSentencePalindromeIterative("RADAR"));
                assertFalse(Palindrome.isSentencePalindromeIterative("FAIL"));
                assertFalse(Palindrome.isSentencePalindromeIterative("Fail"));
                assertFalse(Palindrome.isSentencePalindromeIterative("fail"));
            }

            @Test
            void testSentence() {
                assertTrue(Palindrome.isSentencePalindromeIterative("Murder for a jar of red rum"));
                assertTrue(Palindrome.isSentencePalindromeIterative("Rats live on no evil star"));
                assertTrue(Palindrome.isSentencePalindromeIterative("step on no pets"));
                assertFalse(Palindrome.isSentencePalindromeIterative("This should fail"));
                assertFalse(Palindrome.isSentencePalindromeIterative("this should fail"));
            }

            @Test
            void testSentenceWithPunctuation() {
                assertTrue(Palindrome.isSentencePalindromeIterative("Do geese see God?"));
                assertTrue(Palindrome.isSentencePalindromeIterative("Live on time, emit no evil"));
                assertTrue(Palindrome.isSentencePalindromeIterative("live on time, emit no evil"));
                assertFalse(Palindrome.isSentencePalindromeIterative("Will this fail?"));
                assertFalse(Palindrome.isSentencePalindromeIterative("will this fail?"));
            }
        }

        @Nested
        class Number {

            @Test
            void testSingleLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(0L));
                assertTrue(Palindrome.isNumberPalindromeIterative(1L));
                assertTrue(Palindrome.isNumberPalindromeIterative(3L));
            }

            @Test
            void testBiggerLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(123454321L));
                assertTrue(Palindrome.isNumberPalindromeIterative(1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeIterative(123456789L));
                assertFalse(Palindrome.isNumberPalindromeIterative(1234567890123456789L));
            }

            @Test
            void testNegativeLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(-0L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123454321L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123456789L));
                assertFalse(Palindrome.isNumberPalindromeIterative(-1234567890123456789L));
            }

            @Test
            void testSingleIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(0));
                assertTrue(Palindrome.isNumberPalindromeIterative(1));
                assertTrue(Palindrome.isNumberPalindromeIterative(3));
            }

            @Test
            void testBiggerIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(123454321));
                assertFalse(Palindrome.isNumberPalindromeIterative(123456789));
            }

            @Test
            void testNegativeIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative(-0));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123454321));
                assertFalse(Palindrome.isNumberPalindromeIterative(-123456789));
            }

            @Test
            void testSingleShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 0));
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 1));
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 3));
            }

            @Test
            void testBiggerShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((short) 12321));
                assertFalse(Palindrome.isNumberPalindromeIterative((short) 12345));
            }

            @Test
            void testNegativeShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((short) -0));
                assertFalse(Palindrome.isNumberPalindromeIterative((short) -12321));
                assertFalse(Palindrome.isNumberPalindromeIterative((short) -12345));
            }

            @Test
            void testSingleByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 0));
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 1));
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 3));
            }

            @Test
            void testBiggerByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) 121));
                assertFalse(Palindrome.isNumberPalindromeIterative((byte) 123));
            }

            @Test
            void testNegativeByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeIterative((byte) -0));
                assertFalse(Palindrome.isNumberPalindromeIterative((byte) -121));
                assertFalse(Palindrome.isNumberPalindromeIterative((byte) -123));
            }

        }

        @Nested
        class NumberInRange {
            @Test
            void testEmptyRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(122L, 130L));
            }

            @Test
            void testRangeSingleLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(1L);
                        add(2L);
                        add(3L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(1L, 4L));
            }

            @Test
            void testRangeLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(121L);
                        add(131L);
                        add(141L);
                        add(151L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(120L, 155L));
            }

            @Test
            void testNegativeRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(-131L, 0L));
            }

            @Test
            void testEmptyRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(122, 130));
            }

            @Test
            void testRangeSingleInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(1);
                        add(2);
                        add(3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(1, 4));
            }

            @Test
            void testRangeInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(121);
                        add(131);
                        add(141);
                        add(151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(120, 155));
            }

            @Test
            void testNegativeRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative(-131, 0));
            }

            @Test
            void testEmptyRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) 122, (short) 130));
            }

            @Test
            void testRangeSingleShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 1);
                        add((short) 2);
                        add((short) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) 1, (short) 4));
            }

            @Test
            void testRangeShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 121);
                        add((short) 131);
                        add((short) 141);
                        add((short) 151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) 120, (short) 155));
            }

            @Test
            void testNegativeRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((short) -131, (short) 0));
            }

            @Test
            void testEmptyRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) 122, (byte) 125));
            }

            @Test
            void testRangeSingleByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 1);
                        add((byte) 2);
                        add((byte) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) 1, (byte) 4));
            }

            @Test
            void testRangeByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 101);
                        add((byte) 111);
                        add((byte) 121);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) 100, (byte) 125));
            }

            @Test
            void testNegativeRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeIterative((byte) -125, (byte) 0));
            }
        }
    }

    @Nested
    class Recursive {
        @Nested
        class Word {

            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isWordPalindromeRecursive(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isWordPalindromeRecursive("A"));
                assertTrue(Palindrome.isWordPalindromeRecursive("a"));
            }

            @Test
            void testName() {
                assertTrue(Palindrome.isWordPalindromeRecursive("ABBA"));
                assertTrue(Palindrome.isWordPalindromeRecursive("Ava"));
                assertTrue(Palindrome.isWordPalindromeRecursive("bob"));
                assertFalse(Palindrome.isWordPalindromeRecursive("FAIL"));
                assertFalse(Palindrome.isWordPalindromeRecursive("Fail"));
                assertFalse(Palindrome.isWordPalindromeRecursive("fail"));
            }

            @Test
            void testWord() {
                assertTrue(Palindrome.isWordPalindromeRecursive("madam"));
                assertTrue(Palindrome.isWordPalindromeRecursive("Racecar"));
                assertTrue(Palindrome.isWordPalindromeRecursive("RADAR"));
                assertFalse(Palindrome.isWordPalindromeRecursive("FAIL"));
                assertFalse(Palindrome.isWordPalindromeRecursive("Fail"));
                assertFalse(Palindrome.isWordPalindromeRecursive("fail"));
            }
        }

        @Nested
        class Sentence {
            @Test
            void testEmptyString() {
                assertFalse(Palindrome.isSentencePalindromeRecursive(""));
            }

            @Test
            void testSingleLetter() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("A"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("a"));
            }

            @Test
            void testSingleWord() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("madam"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("Racecar"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("RADAR"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("FAIL"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("Fail"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("fail"));
            }

            @Test
            void testSentence() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("Murder for a jar of red rum"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("Rats live on no evil star"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("step on no pets"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("This should fail"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("this should fail"));
            }

            @Test
            void testSentenceWithPunctuation() {
                assertTrue(Palindrome.isSentencePalindromeRecursive("Do geese see God?"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("Live on time, emit no evil"));
                assertTrue(Palindrome.isSentencePalindromeRecursive("live on time, emit no evil"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("Will this fail?"));
                assertFalse(Palindrome.isSentencePalindromeRecursive("will this fail?"));
            }
        }

        @Nested
        class Number {

            @Test
            void testSingleLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(0L));
                assertTrue(Palindrome.isNumberPalindromeRecursive(1L));
                assertTrue(Palindrome.isNumberPalindromeRecursive(3L));
            }

            @Test
            void testBiggerLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(123454321L));
                assertTrue(Palindrome.isNumberPalindromeRecursive(1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(123456789L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(1234567890123456789L));
            }

            @Test
            void testNegativeLongNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(-0L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123454321L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-1234567890987654321L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123456789L));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-1234567890123456789L));
            }

            @Test
            void testSingleIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(0));
                assertTrue(Palindrome.isNumberPalindromeRecursive(1));
                assertTrue(Palindrome.isNumberPalindromeRecursive(3));
            }

            @Test
            void testBiggerIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(123454321));
                assertFalse(Palindrome.isNumberPalindromeRecursive(123456789));
            }

            @Test
            void testNegativeIntegerNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive(-0));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123454321));
                assertFalse(Palindrome.isNumberPalindromeRecursive(-123456789));
            }

            @Test
            void testSingleShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 0));
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 1));
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 3));
            }

            @Test
            void testBiggerShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) 12321));
                assertFalse(Palindrome.isNumberPalindromeRecursive((short) 12345));
            }

            @Test
            void testNegativeShortNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((short) -0));
                assertFalse(Palindrome.isNumberPalindromeRecursive((short) -12321));
                assertFalse(Palindrome.isNumberPalindromeRecursive((short) -12345));
            }

            @Test
            void testSingleByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 0));
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 1));
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 3));
            }

            @Test
            void testBiggerByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) 121));
                assertFalse(Palindrome.isNumberPalindromeRecursive((byte) 123));
            }

            @Test
            void testNegativeByteNumber() {
                assertTrue(Palindrome.isNumberPalindromeRecursive((byte) -0));
                assertFalse(Palindrome.isNumberPalindromeRecursive((byte) -121));
                assertFalse(Palindrome.isNumberPalindromeRecursive((byte) -123));
            }

        }

        @Nested
        class NumberInRange {
            @Test
            void testEmptyRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(122L, 130L));
            }

            @Test
            void testRangeSingleLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(1L);
                        add(2L);
                        add(3L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(1L, 4L));
            }

            @Test
            void testRangeLong() {
                List<Long> expected = new ArrayList<>() {
                    {
                        add(121L);
                        add(131L);
                        add(141L);
                        add(151L);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(120L, 155L));
            }

            @Test
            void testNegativeRangeLong() {
                List<Long> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(-131L, 0L));
            }

            @Test
            void testEmptyRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(122, 130));
            }

            @Test
            void testRangeSingleInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(1);
                        add(2);
                        add(3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(1, 4));
            }

            @Test
            void testRangeInteger() {
                List<Integer> expected = new ArrayList<>() {
                    {
                        add(121);
                        add(131);
                        add(141);
                        add(151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(120, 155));
            }

            @Test
            void testNegativeRangeInteger() {
                List<Integer> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive(-131, 0));
            }

            @Test
            void testEmptyRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) 122, (short) 130));
            }

            @Test
            void testRangeSingleShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 1);
                        add((short) 2);
                        add((short) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) 1, (short) 4));
            }

            @Test
            void testRangeShort() {
                List<Short> expected = new ArrayList<>() {
                    {
                        add((short) 121);
                        add((short) 131);
                        add((short) 141);
                        add((short) 151);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) 120, (short) 155));
            }

            @Test
            void testNegativeRangeShort() {
                List<Short> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((short) -131, (short) 0));
            }

            @Test
            void testEmptyRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) 122, (byte) 125));
            }

            @Test
            void testRangeSingleByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 1);
                        add((byte) 2);
                        add((byte) 3);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) 1, (byte) 4));
            }

            @Test
            void testRangeByte() {
                List<Byte> expected = new ArrayList<>() {
                    {
                        add((byte) 101);
                        add((byte) 111);
                        add((byte) 121);
                    }
                };
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) 100, (byte) 125));
            }

            @Test
            void testNegativeRangeByte() {
                List<Byte> expected = new ArrayList<>();
                assertEquals(expected, Palindrome.getAllNumberPalindromesInRangeRecursive((byte) -125, (byte) 0));
            }
        }
    }
}
```

คำตอบ

2 Bobby Aug 27 2020 at 23:51

สิ่งนี้ดูดีอ่านสนุกแม้จะซ้ำซาก


package com.gr;

แพคเกจควรเชื่อมโยงกับผู้แต่งดังนั้นควรเป็นcom.github.lucifer.palindromeตัวอย่างเช่น แต่ขึ้นอยู่กับว่ามีการเผยแพร่โค้ดนี้หรือไม่ก็ไม่สำคัญในกรณีนี้


นี่จะเป็นแบบฝึกหัดที่ดีสำหรับการเขียนโปรแกรมเชิงวัตถุโดยการสร้างอินเทอร์เฟซและมีการใช้งานแยกกัน

public interface PalindromeTester;
public class IterativePalindromeTester implements PalindromeTester;
public class RecursivePalindromeTester implements PalindromeTester;

นั่นจะช่วยแก้ปัญหาครึ่งหนึ่งของคำถามที่มากเกินไปของคุณ อีกครึ่งหนึ่งคือNumber/ CharArray/ Wordสิ่งคุณควรทิ้งสิ่งนั้นจากชื่อเนื่องจากเห็นได้ชัดจากพารามิเตอร์ที่ยอมรับ นอกจากนี้ยังจะล้างกรณีทดสอบของคุณเล็กน้อยเนื่องจากเป็นคลาสทดสอบที่แตกต่างกันสองคลาส คุณยังมีabstractการทดสอบระดับและขยายที่และตั้งค่าได้เพียงอินสแตนซ์ที่แตกต่างกันในPalindromeTesterBeforeEach

อีกประการหนึ่งคือถ้าคุณสามารถอยู่ได้ด้วยการขยายค่าที่กำหนดคุณสามารถระบุวิธีการเดียวที่ยอมรับ a long. ใด ๆshort/ intจะถูกแปลงโดยอัตโนมัติ แต่แน่นอนว่าต้องมีการดำเนินการที่กว้างขึ้นภายใต้ประทุน

นอกจากนี้ยังมีNumber/ BigIntegerซึ่งคุณอาจต้องการรวมไว้ด้วย

ในหมายเหตุอื่นคุณสามารถchar[]ให้ความCharSequenceสำคัญกับ ต่อมาเป็นฐานสำหรับคลาสต่างๆมากมาย (รวมถึงStringไม่จำเป็นต้องโอเวอร์โหลด) และแสดงถึงเจตนาที่ดีขึ้นเล็กน้อย เกี่ยวกับเรื่องนี้หากคุณยอมรับจดหมายใด ๆ รวมถึงภาษาต่างประเทศคุณมักต้องการทำงานกับจุดรหัส ( int) แทนchars ใน UTF-8 / UTF-16 ไม่ใช่ตัวอักษรทั้งหมดเป็นเพียงไบต์เดียว แต่สามารถประกอบด้วยไบต์แบบทวีคูณได้ (มากถึงสี่ตัวint)


 * Returns a boolean of whether the number of type short (32,768 to 32,767)

อย่าใส่ค่าต่ำสุด / สูงสุดในเอกสารประกอบ ประการแรกมันซ้ำซ้อนเนื่องจากเห็นได้ชัดจากประเภทที่ใช้ ประการที่สองมีแนวโน้มที่จะพิมพ์ผิดเช่นในกรณีนี้


        List<Long> results = new ArrayList<>();
        for (long number = start; number != end; number++)
            if (isNumberPalindromeRecursive(number))
                results.add(number);

โปรดทราบว่านี่เป็นการทำกล่องอัตโนมัติซึ่งหมายความว่าระบบจะแปลงแบบดั้งเดิมเป็นObjectอินสแตนซ์โดยอัตโนมัติ


for (int i = 0; i != formattedChars.length / 2; i++)

ครั้งแรกที่ฉันสนับสนุนถาวรของชื่อ "ของจริง" สำหรับตัวแปรห่วงเหมือนหรือindexcounter

ประการที่สองคุณควรแก้ไขเงื่อนไขการแตกหักให้มีประสิทธิภาพมากขึ้นโดยตรวจสอบว่าค่านั้นเท่ากับหรือมากกว่าความยาวครึ่งหนึ่ง


        boolean isPalindrome = true;
        for (int i = 0; i != formattedChars.length / 2; i++)
            if (formattedChars[i] != formattedChars[(formattedChars.length - 1) - i]) {
                isPalindrome = false;
                break;
            }
        return isPalindrome;

อย่าเก็บผลลัพธ์ส่งกลับโดยตรง

        for (int i = 0; i != formattedChars.length / 2; i++)
            if (formattedChars[i] != formattedChars[(formattedChars.length - 1) - i])
                return false;
        
        return true;
```
1 TorbenPutkonen Aug 27 2020 at 11:14

การมีอินเทอร์เฟซทั่วไปสำหรับอัลกอริทึมจะช่วยแก้ปัญหาการทำซ้ำโค้ดระหว่างการทดสอบสำหรับการใช้งานที่แตกต่างกัน คุณสร้างชุดการทดสอบที่การใช้งานอินเทอร์เฟซใด ๆ ควรเป็นไปตามนั้นจากนั้นเพียงแค่โยนการใช้งานที่แตกต่างกันไป (ดูL ในหลักการ SOLID )

สำหรับการทดสอบอินพุตสตริงธรรมดาชุดใหญ่ให้ใส่รายการที่ถูกต้องลงในอาร์เรย์หนึ่งและรายการที่ไม่ถูกต้องในอีกอาร์เรย์และสร้างการทดสอบสองรายการที่วนซ้ำในแต่ละอาร์เรย์