DEV Community

Johns Code
Johns Code

Posted on

Find all palindromes in a string

For this post, we're going to build off 2 of the previous posts in the series.

Write a golang function that finds all palindromes in a string.

I will interpret this to mean 'from the given string, find all strings within it that are palindromes'

In a previous post, we created a function to find all unique strings from a given string.

In the last post, we created a function to check if a string is a palindrome.

Using these 2 together, we can find all possible palindromes in a string.

func FindAllPalindromes(str string) []string {
    allPalindromes := []string{}
    uniqueStrings := uniquecombos.FindUniqueCombinations(str)
    for _, uniqueString := range uniqueStrings {
        if palindromecheck.PalindromeCheck(uniqueString) {
            allPalindromes = append(allPalindromes, uniqueString)
        }
    }
    return allPalindromes
}
Enter fullscreen mode Exit fullscreen mode

It turns out, the unit test has a curveball worth noting here.

The FindAllPalindromes function builds the result array in whatever order the palindromes are found. This may or may not be the order of the 'expected' result in the unit test.
For example, the string, 'aba', has 4 palindromes: 'a', 'aa', 'aba', and 'b'. However, FindAllPalindromes returns 'a', 'aba', 'aa', and 'b'.

We have several options here:

  • write a function that compares two arrays without regard to order, ie the 2 arrays have the same elements and length.

  • sort both the expected and result arrays, then compare

For simplicity, I chose the second option but have built the expected result of the test cases in presorted form to squeeze a little time off test runs.

func TestFindAllPalindromes(t *testing.T) {
    testCases := []struct {
        input    string
        expected []string
    }{
        // note that expected arrays have been presorted for quicker test runs
        {"", []string{}},
        {"a", []string{"a"}},
        {"ab", []string{"a", "b"}},
        {"aba", []string{"a", "aa", "aba", "b"}},
        {"aab", []string{"a", "aa", "b"}},
        {"abcba", []string{"a", "aa", "aba", "abba", "abcba", "aca", "b", "bb", "bcb", "c"}},
    }

    for _, tc := range testCases {
        results := FindAllPalindromes(tc.input)
        // sort result to match expected order
        slices.Sort(results)
        if !reflect.DeepEqual(results, tc.expected) {
            t.Errorf("findUniqueCombinations(%q) = %v; expected %v", tc.input, results, tc.expected)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

How can we make this better?

Post your thoughts in the comments.

Thanks!

The code for this post and all posts in this series can be found here

Top comments (0)