Skip to content

Instantly share code, notes, and snippets.

@mchandschuh
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mchandschuh/3f0bb998c7ff72c9d489 to your computer and use it in GitHub Desktop.
Save mchandschuh/3f0bb998c7ff72c9d489 to your computer and use it in GitHub Desktop.
Find all unique palindromes of any length in a source string
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace Genetic.Tests
{
[TestFixture]
public class PalindromeTests
{
[Test]
public void FindAllPalindromes()
{
const string source = "abcdcbaba";
var palindromes_described = FindAllUniquePalindromes_Described(source);
var palindromes_better = FindAllUniquePalindromes_Better(source);
Assert.IsTrue(palindromes_described.SequenceEqual(palindromes_better));
foreach (var palindrome in palindromes_described)
{
Console.WriteLine(palindrome);
}
/*
* Output:
a
abcdcba
b
bcdcb
c
cdc
d
bab
aba
*/
}
/// <summary>
/// Searches the source string for all unique palindromes of any length
/// </summary>
/// <remarks>
/// This is the implementation described over the phone
/// </remarks>
/// <param name="source">The source string to search</param>
/// <returns>A list of all palindromes found in source</returns>
private static HashSet<string> FindAllUniquePalindromes_Described(string source)
{
// result set
var palindromes = new HashSet<string>();
// for each character in source construct each substring and then test for palindrome
for (int i = 0; i < source.Length; i++)
{
var queue = new Queue<char>(source.Length - i);
for (int j = i; j < source.Length; j++)
{
// add the next character to our consider set
queue.Enqueue(source[j]);
// determine if this is a palindrome
if (queue.SequenceEqual(queue.Reverse()))
{
palindromes.Add(new string(queue.ToArray()));
}
}
}
return palindromes;
}
/// <summary>
/// Searches the source string for all unique palindromes of any length
/// </summary>
/// <remarks>
/// This is a better implementation after looking at the code, and honestly, laid to to
/// sleep and figured it a good idea to show a better way instead of just the way I initially
/// described.
/// </remarks>
/// <param name="source">The source string to search</param>
/// <returns>A list of all palindromes found in source</returns>
private static HashSet<string> FindAllUniquePalindromes_Better(string source)
{
// result set
var palindromes = new HashSet<string>();
// for each character in source construct each substring and then test for palindrome
for (int i = 0; i < source.Length; i++)
{
for (int j = i; j < source.Length; j++)
{
string consider = source.Substring(i, j - i + 1);
// determine if this is a palindrome
if (IsPalindrome(consider))
{
palindromes.Add(consider);
}
}
}
return palindromes;
}
/// <summary>
/// Determines if the specified string is a palindrome (mirrored)
/// </summary>
/// <param name="source">The source string to check</param>
/// <returns>True if the string is a palindrome</returns>
private static bool IsPalindrome(string source)
{
for (int i = 0; i < source.Length/2; i++)
{
// palindromes are mirrored, so keep comparing the ends until one doesn't match
if (source[i] != source[source.Length - i - 1])
{
return false;
}
}
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment