/// <summary> /// The main function to compute unique longest palindromes /// </summary> /// <param name="numOfPalindromes"> a positive integer </param> /// <param name="s"> the string to search palindromes in. Not null</param> /// <returns>a data structrue LongestUniquePalindromes containing at most numOfPalindromes unique longest palindromes </returns> public static LongestUniquePalindromes GetLongestUniquePalindromes(int numOfPalindromes, string s) { if (s == null) { throw new ArgumentNullException("s"); } if (numOfPalindromes < 1) { throw new ArgumentOutOfRangeException("numOfPalindromes"); } LongestUniquePalindromes longestPalindromes = new LongestUniquePalindromes(); HashSet <string> nonUniquePalindromes = new HashSet <string>(); bool foundAllPalindromes = false; //in decreasing string length for (int i = s.Length; i > 0; i--) { //there are (s.Length-i+1) possible partitions of length i. examine whether they are palindromes. int numberOfPartitions = s.Length - i + 1; for (int j = 0; j < numberOfPartitions; j++) { string substringToCheck = s.Substring(j, i); bool isPalindrome = PalindromeRecognizer.IsPalindrome(substringToCheck); if (isPalindrome) { PalindromeData candidatePalindrome = new PalindromeData(j, i, substringToCheck); UpdateLongestPalindromes(longestPalindromes, nonUniquePalindromes, candidatePalindrome); } } //we have examined here all palindromes of length i. //check now if we have sufficient number of palindromes to return //IMPORTANT: we must traverse over all partitions of length i, in order to make //sure that we capture only the unique palindromes of that length. if (longestPalindromes.Count >= numOfPalindromes) { foundAllPalindromes = true; longestPalindromes.RemoveRange(numOfPalindromes, longestPalindromes.Count - numOfPalindromes); break; } } //if we have not reached numOfPalindromes, add the empty string (a palindrome of length 0) //and return with whatever number of longest palindrome we have found. //i.e., Min ( longestPalindrome.Count, numOfPalindromes). if (!foundAllPalindromes) { PalindromeData candidatePalindrome = new PalindromeData(0, 0, string.Empty); longestPalindromes.Add(candidatePalindrome); } return(longestPalindromes); }
public bool Contains(PalindromeData candidatePalindrome) { foreach (var item in longestPalindromes) { if (candidatePalindrome.Palindrome == item.Palindrome) { return(true); } } return(false); }
public bool IntervalContains(PalindromeData candidatePalindrome) { foreach (var item in longestPalindromes) { if (item.Palindrome.Contains(candidatePalindrome.Palindrome) && item.Palindrome != candidatePalindrome.Palindrome) { return(true); } } return(false); }
public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } PalindromeData data = (PalindromeData)obj; return(Palindrome == data.Palindrome); //palindromes with different intervals but same string are equal. }
public void Remove(PalindromeData candidatePalindrome) { longestPalindromes.Remove(candidatePalindrome); }
public void Add(PalindromeData candidatePalindrome) { longestPalindromes.Add(candidatePalindrome); }
private static void UpdateLongestPalindromes(LongestUniquePalindromes longestPalindromes, HashSet <string> nonUniquePalindromes, PalindromeData candidatePalindrome) { //if the candidate palindrome is strictly contained within another palindrome, it is not longest, or not unique: continue if (longestPalindromes.IntervalContains(candidatePalindrome)) { return; } //if the candidate palindrome has already been recognized as not unique, continue. if (nonUniquePalindromes.Contains(candidatePalindrome.Palindrome)) { return; } if (!longestPalindromes.Contains(candidatePalindrome)) { longestPalindromes.Add(candidatePalindrome); } else { //a palindrome of an equal length but different interval has been encountered before, it is not unique. //IMPORTANT: it also means that the palindrome that we have encountered is not unique as well. //remove it from the longest palindromes, and recognize it as non-unique. longestPalindromes.Remove(candidatePalindrome); nonUniquePalindromes.Add(candidatePalindrome.Palindrome); } }