From f4806eb48cabe811ebc48117f787b55829108739 Mon Sep 17 00:00:00 2001 From: Jitendra_Sharma Date: Wed, 2 Jan 2019 16:47:56 +0530 Subject: [PATCH] manacher's algorithm to find palindromic string (#676) manacher's algorithm to find palindromic string in linear time complexity --- strings/manacher.py | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 strings/manacher.py diff --git a/strings/manacher.py b/strings/manacher.py new file mode 100644 index 000000000..9a44b19ba --- /dev/null +++ b/strings/manacher.py @@ -0,0 +1,52 @@ +# calculate palindromic length from center with incresmenting difference +def palindromic_length( center, diff, string): + if center-diff == -1 or center+diff == len(string) or string[center-diff] != string[center+diff] : + return 0 + return 1 + palindromic_length(center, diff+1, string) + +def palindromic_string( input_string ): + """ + Manacher’s algorithm which finds Longest Palindromic Substring in linear time. + + 1. first this conver input_string("xyx") into new_string("x|y|x") where odd positions are actual input + characters. + 2. for each character in new_string it find corresponding length and store, + a. max_length + b. max_length's center + 3. return output_string from center - max_length to center + max_length and remove all "|" + """ + max_length = 0 + + # if input_string is "aba" than new_input_string become "a|b|a" + new_input_string = "" + output_string = "" + + # append each character + "|" in new_string for range(0, length-1) + for i in input_string[:len(input_string)-1] : + new_input_string += i + "|" + #append last character + new_input_string += input_string[-1] + + + # for each character in new_string find corresponding palindromic string + for i in range(len(new_input_string)) : + + # get palindromic length from ith position + length = palindromic_length(i, 1, new_input_string) + + # update max_length and start position + if max_length < length : + max_length = length + start = i + + #create that string + for i in new_input_string[start-max_length:start+max_length+1] : + if i != "|": + output_string += i + + return output_string + + +if __name__ == '__main__': + n = input() + print(palindromic_string(n))