I'm trying to find the shortest palindrome that one can create from S by by adding 0 or more characters in front of it. For example the shortest palindrome can be constructed from 'baaa' is 'aaabaaa'. The two functions that I'm using are given below. This works for this case for doesn't yield the shortest result in all cases.
public static boolean checkPalindrome(String s){
for (int i = 0; i < s.length()/2; i++) {
if (s.charAt(i) != s.charAt(s.length() - i - 1)) return false;
}
return true;
}
public static int makePalindrome(String s){
int min = 0;
StringBuilder str = new StringBuilder(s);
for (int i = 1; i < s.length() ; i++) {
str.insert(0, s.charAt(i));
if (checkPalindrome(str.toString()) == true) {
min = str.length();
break;
}
}
return min;
}
I can't seem to figure out what logical step am I missing.
Your helper method checkPalindrome
seems correct. Your thinking is also correct (append characters until the result is a palindrome), but the way you're going about it is wrong.
To reiterate: Our logic is, while our result is not a palindrome, take the next character from the end (moving towards the start of the string) and append it to the prefix. So for the string "abcd"
, we would try
"" + "abcd"
-> "abcd"
-> false "d" + "abcd"
-> "dabcd"
-> false "dc" + "abcd"
-> "dcabcd"
-> false "dcb" + "abcd"
-> "dcbabcd"
-> true, terminate Here's a fixed version:
public static String makePalindrome(String base){
String pref = "";
int i = base.length() - 1;
while(! checkPalindrome(pref + base)){
pref = pref + base.charAt(i);
i --;
}
return pref + base;
}
IDEONE: http://ideone.com/tawjmG
We can find the shortest Palindrome using the following logic:
Find the midpoint, loop from 0 to midpoint, length-1 to midpoint.
If palindrome, return
If not palindrome, add 1 to midpoint, do same logic
In code:
static String shortestPalindrome(String s) {
if (s.length() == 1) return s;
return recShortestPalindrome(s, s.length()>>1, 0);
}
static String recShortestPalindrome(String s, int mid, int add) {
// AABBA[X]
int fakeLen = s.length() + add;
for (int i = 0; i < mid; i++) {
char c1 = s.charAt(i);
int p1 = fakeLen - 1 - i;
if (p1 < s.length()) {
char c2 = s.charAt(p1);
if (c2 != c1) {
return recShortestPalindrome(s, mid+1, add+1);
}
}
}
// found a pattern that works
String h1 = s.substring(0, mid);
String h2 = new StringBuilder(h1).reverse().toString();
String ret = h1+h2;
int midPoint = ret.length()/2;
if (ret.length()%2 == 0 && ret.length() >= 2) {
char c1 = ret.charAt(midPoint);
char c2 = ret.charAt(midPoint-1);
if (c1 == c2) {
return ret.substring(0, midPoint) + ret.substring(midPoint+1, ret.length());
}
}
return h1+h2;
}
I am not sure i understand the question but from what i understood you want to turn Strings like Hello to olleHello To do this, loop trhough each char of the string with like:
String example = "Hello There Mate"; //our string
StringBuilder exampleBuilder = new StringBuilder();
for(int i=example.length()-1; i>0; i--)
exampleBuilder.append(example.charAt(i));
//Our loop, the reason why it is example.lenght-1
//is because we want the first letter to appear only
//1 time :)
String finalString = exampleBuilder.toString()+example;
//The final string, should be 'olleHello'
System.out.println(finalString);
Hope thats what you are looking for :D
Python Solution:
def isPalindrome(x):
if x == "":
return False
r = ""
r = str(x)
r = r[::-1]
return True if x == r else False
def makePalindrome(my_str):
pref = ""
i = len(my_str) - 1
while isPalindrome(pref + my_str) == False:
pref = pref + my_str[i]
i -= 1
return pref + my_str
my_str = "abcd"
print(makePalindrome(my_str))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.