This is a recursion program to test whether or not a sentence is a palindrome. It will run correctly if I write "bob" but not for "Madam I'm Adam" because of the caps and symbols. We are required to use a clean string method(?) to eliminate the spaces, symbols, and caps. This is what I have but I don't believe I've implemented it correctly. Could someone tell me how to improve/fix this? (Yes, I've looked all over the internet)
import java.util.Scanner;
public class Palindromes {
public static boolean isaPalindrome(String s) {
String cleanedString = clean(s);
if (s.length() == 0 || s.length() == 1)
return true;
if (s.charAt(0) == s.charAt(s.length() - 1))
return isaPalindrome(s.substring(1, s.length() - 1));
return false;
}
public static void main(String[] args) {
System.out.print("Enter a palindrome to test: ");
Scanner console = new Scanner(System.in);
String inStr = console.nextLine();
if (isaPalindrome(inStr)) {
System.out.printf("The input string, %s, is a palindrome.\n",
inStr);
reverseStr(inStr); // must be recursive!
System.out.println();
} else {
System.out.printf("The input string, %s, is not a palindrome.\n",
inStr);
}
}
private static String clean(String s) {
String cleaned = "";
return cleaned;
}
private static String reverseStr(String inStr) {
if ((null == inStr) || (inStr.length() <= 1)) {
return inStr;
}
return reverseStr(inStr.substring(1)) + inStr.charAt(0);
}
}
Your recursive method isaPalindrome is correct. If you want to further improve it, I would suggest you to avoid using subString to create parameters for your recursive call, this will create too many strings.
Instead, keep track of the positions of the characters in the original string that you are comparing:
public static boolean isaPalindrome(String s, int leftIndex, int rightIndex) {
if (leftIndex == rightIndex) return true;
if (s.charAt(leftIndex) == s.charAt(rightIndex))
return isaPalindrome(s, leftIndex + 1, rightIndex - 1);
return false;
}
You would invoke the method as: isaPalindrome(inStr, 0, inStr.length() - 1)
As for your clean method, you can use toLowerCase and Character.isLetter method to process the original string.
private static String clean(String s) {
String lowerCaseString = s.toLowerCase();
StringBuffer result = new StringBuffer();
for (int i = 0; i < lowerCaseString.length(); ++i) {
if (Character.isLetter(lowerCaseString.charAt(i))) {
result.append(lowerCaseString.charAt(i));
}
}
return result.toString();
}
Try this:
public static void main(final String[] args) {
final String unclean = "Madam I'm Adam";
final String clean = cleanString(unclean);
System.out.println("Clean string is: " + clean);
}
static private String cleanString(final String pTheString) {
final StringBuilder sb = new StringBuilder(pTheString.length());
for (final char c : pTheString.toCharArray()) {
switch (c) {
// ignore all those
case ' ':
case '\'':
case '.':
break;
// write the rest
default:
sb.append(c);
}
}
return sb.toString().toLowerCase();
}
Related
I'm making a Palindrome Generator. Basically the user inputs a word or sentence and the program outputs whether or not its a Palindrome, which is a word that is spelled the same forwards and backwards like "wow" or "racecar". My program works fine, however the output text will repeat itself like fifty times and I can't seem to figure out where the issue is without messing everything up. Help would be appreciated.
import javax.swing.JOptionPane;
public class palindromedectector {
public static void main(String[] args) {
String testStrings = "";
testStrings = JOptionPane.showInputDialog("Enter word: ");
for (int i = 0; i < testStrings.length(); i++)
{
System.out.print("\"" + testStrings + "\"");
if (isPalindrome(stripString(testStrings)))
System.out.println(" is a palindrome.");
else
System.out.println(" is not a palindrome.");
}
}
public static String stripString(String strip)
{
strip = strip.toUpperCase();
String stripped= "";
for (int i= 0; i< strip.length(); i++)
{
if (Character.isLetter(strip.charAt(i)))
stripped += strip.charAt(i);
}
return stripped;
}
public static boolean isPalindrome (String str)
{
boolean status = false;
if (str.length() <= 1)
status = true;
else if (str.charAt(0) == str.charAt(str.length()-1))
{
status = isPalindrome (str.substring(1, str.length()-1));
}
return status;
}
}
Main issue is that you run isPalindrome check for the same string in the loop, probably you wanted to run multiple checks
public static void main(String[] args) {
final int attempts = 5;
for (int i = 0; i < attempts; i++) {
String word = JOptionPane.showInputDialog("Enter word: ");
System.out.print("\"" + word + "\"");
if (isPalindrome(stripString(word))) {
System.out.println(" is a palindrome.");
} else {
System.out.println(" is not a palindrome.");
}
}
}
Also, the main functionality may be implemented in a shorter way:
// use regexp to get rid of non-letters
private static String stripString(String word) {
if (null == word || word.isEmpty()) {
return word;
}
return word.replaceAll("[^A-Za-z]", "").toUpperCase(); // remove all non-letters
}
// use Java Stream API to check letters using half of word length
private static boolean isPalindrome(String word) {
if (null == word) {
return false;
}
final int len = word.length();
if (len < 2) {
return true;
}
return IntStream.range(0, len/2)
.allMatch(i -> word.charAt(i) == word.charAt(len - 1 - i));
}
Basic problem: You are testing if the word is a palindrome testStrings.length() times, ie once for every letter in the word, rather than just once.
Remove the for loop in your main() method.
I want to write codes using a static recursive method in Java, cleanString(String s) that accepts a string of letters s and returns a string where adjacent letters that are the same are replaced by a single occurrence of that letter. The method is case-sensitive.
For example:
cleanString("sensssaatiionnaallll!") -> "sensational!"
cleanString("PPProoggggraamm") -> "Program"
cleanString("Lletterriiing") -> "Lletering"
Try this:
public class Main {
public static void main(String[] args) {
System.out.println(cleanString("sensssaatiionnaallll!"));
}
static String cleanString(String input)
{
if(input.length()<1) //To stop infinite recursion
return input;
var first = input.charAt(0);
var count = input.chars().takeWhile(x -> x == first).count();
return first + cleanString(input.substring((int)count));
}
}
First, it checks if the length of the string is less than 1. If it is, return the string itself (which is empty) and stop the recursion.
Next get the first character of the string. (e.g PPProoggggraamm -> P)
Get the number of characters in the start that equal the first character (3 in the case of PPProoggggraamm)
Call the function again, but this time lopping off the first n characters from the above step, and prepending the first character. ('P' + cleanString("rooggggraamm"))
Shortest recursive code to remove adjacent characters from the input string.
public class StackOverflow {
static String cleanString(String input) {
return input==null || input.length()<=1?input:cleanStringWrapper(input.substring(1),input.substring(0,1));
}
static String cleanStringWrapper(String input, String result) {
if (input.length() - 1 <= 0) {
return result+(result.charAt(result.length() - 1)!=input.charAt(0)?input:"");
} else {
return cleanStringWrapper(input.substring(1), result+(result.charAt(result.length() - 1) != input.charAt(0)?input.charAt(0):""));
}
}
public static void main(String[] args)
{
System.out.println(cleanString("OOPS"));
}
}
Output:
cleanString("sensssaatiionnaallll!") -> "sensational!"
cleanString("PPProoggggraamm") -> "Program"
cleanString("Lletterriiing") -> "Lletering"
cleanString("Gooooogle") -> "Gogle"
cleanString("ABC") -> "ABC"
cleanString("A") -> "A"
cleanString("") -> ""
cleanString(null) -> null
It just generate a new String and exclude the repeat characters.
static String cleanString(String input) {
if(input == null) return null;
char lastChar = 0;
StringBuilder output = new StringBuilder(input.length());
for (int i=0,n=input.length(); i<n; i++) {
char c = input.charAt(i);
if(c != lastChar) {
lastChar = c;
output.append(c);
}
}
return output.toString();
}
Recursive method:
public class Example {
public static int main(String[] args) {
String input = "sensssaatiionnaallll";
String output = cleanString(input, 0);
System.out.println(output); // print: sensational
return 0;
}
private static String cleanString(String input, int index) {
if(input == null) return "";
if(index >= input.length()) return "";
StringBuilder output = new StringBuilder();
char current = input.charAt(index);
int nextIndex = index + 1;
if(nextIndex >= input.length()) {
return output.append(current).toString();
}
char next = input.charAt(nextIndex);
if (current != next) {
output.append(current);
}
output.append(cleanString(input, nextIndex));
return output.toString();
}
}
Why you want to make static method for that?
Whay i understood is that you want to remove repeated characters from your input string.
You can do it below code as well.
StringBuilder sb = new StringBuilder();
str.chars().distinct().forEach(c -> sb.append((char) c));
If you want you can make a method of this 2 lines as a feature in your code.
Hope this helps!
public static void main(String[] args)
{
Scanner sentence = new Scanner(System.in);
System.out.println("This program will determine if an inputted phrase is a palindrome.");
System.out.println(" ");
System.out.println("Enter a phrase, word, or sentence:");
String a = sentence.nextLine();
String b = a.toLowerCase().replaceAll("[^a-z]"," "); //as long as the words are spelt the same way, the caps don't matter and it ignores spaces and punctuation
System.out.println();
System.out.println(palindromeChecker(b)); //calls method
}
public static String palindromeChecker(String b)
{
String reverse = new StringBuilder(b).reverse().toString();
String c;
if(b.equals(reverse)) {
c = "The word " +b+ " is a palindrome"; }
else {
c = "The word " +b+ " is not a palindrome"; }
return c;
}
}
My, problem is that for example, if i do Eva, can I see bees in a cave? It should be a palindrome, however it's not can u please help me with this and please try not to make it complicated.
Replace:
String b = a.toLowerCase().replaceAll("[^a-z]"," ");
With
String b = a.toLowerCase().replaceAll("[^a-z]","");
Otherwise, you're replacing non-alphabetical characters with spaces, which can influence the checking of the reverse String.
You need to remove all non-letters from your string:
public class Palindrome {
public static String strip(String s) {
return s.toLowerCase().replaceAll("[^a-z]", "");
}
public static boolean isPalindrome(String s) {
for (int i = 0; i < s.length() / 2; i++) {
if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println(strip("Eva, can I see bees in a cave?"));
System.out.println(isPalindrome(strip("Eva, can I see bees in a cave?")));
}
}
Output:
evacaniseebeesinacave
true
public class PalindromeStringWithReverse {
public static void main(String[] args) {
String str = "21raceca r12";
str = str.replaceAll(" ", "");
boolean isPalindrome = false;
for (int i = 0; i < str.length() / 2; i++) {
if (str.charAt(i) == str.charAt((str.length() - 1) - i)) {
isPalindrome = true;
continue;
}
isPalindrome = false;
}
if (isPalindrome) {
System.out.println("Palindrome");
} else {
System.out.println("not palindrome");
}
}
}
This question already has answers here:
Check string for palindrome
(42 answers)
Closed 7 years ago.
I want to check if a string is a palindrome or not. I would like to learn an easy method to check the same using least possible string manipulations
Using reverse is overkill because you don't need to generate an extra string, you just need to query the existing one. The following example checks the first and last characters are the same, and then walks further inside the string checking the results each time. It returns as soon as s is not a palindrome.
The problem with the reverse approach is that it does all the work up front. It performs an expensive action on a string, then checks character by character until the strings are not equal and only then returns false if it is not a palindrome. If you are just comparing small strings all the time then this is fine, but if you want to defend yourself against bigger input then you should consider this algorithm.
boolean isPalindrome(String s) {
int n = s.length();
for (int i = 0; i < (n/2); ++i) {
if (s.charAt(i) != s.charAt(n - i - 1)) {
return false;
}
}
return true;
}
For the least lines of code and the simplest case
if(s.equals(new StringBuilder(s).reverse().toString())) // is a palindrome.
Here is a simple one"
public class Palindrome {
public static void main(String [] args){
Palindrome pn = new Palindrome();
if(pn.isPalindrome("ABBA")){
System.out.println("Palindrome");
} else {
System.out.println("Not Palindrome");
}
}
public boolean isPalindrome(String original){
int i = original.length()-1;
int j=0;
while(i > j) {
if(original.charAt(i) != original.charAt(j)) {
return false;
}
i--;
j++;
}
return true;
}
}
You can try something like this :
String variable = ""; #write a string name
StringBuffer rev = new StringBuffer(variable).reverse();
String strRev = rev.toString();
if(variable.equalsIgnoreCase(strRev)) # Check the condition
Here's a good class :
public class Palindrome {
public static boolean isPalindrome(String stringToTest) {
String workingCopy = removeJunk(stringToTest);
String reversedCopy = reverse(workingCopy);
return reversedCopy.equalsIgnoreCase(workingCopy);
}
protected static String removeJunk(String string) {
int i, len = string.length();
StringBuffer dest = new StringBuffer(len);
char c;
for (i = (len - 1); i >= 0; i--) {
c = string.charAt(i);
if (Character.isLetterOrDigit(c)) {
dest.append(c);
}
}
return dest.toString();
}
protected static String reverse(String string) {
StringBuffer sb = new StringBuffer(string);
return sb.reverse().toString();
}
public static void main(String[] args) {
String string = "Madam, I'm Adam.";
System.out.println();
System.out.println("Testing whether the following "
+ "string is a palindrome:");
System.out.println(" " + string);
System.out.println();
if (isPalindrome(string)) {
System.out.println("It IS a palindrome!");
} else {
System.out.println("It is NOT a palindrome!");
}
System.out.println();
}
}
Enjoy.
public boolean isPalindrom(String text) {
StringBuffer stringBuffer = new StringBuffer(text);
return stringBuffer.reverse().toString().equals(text);
}
I guess this is simple way to check palindrome
String strToRevrse = "MOM";
strToRevrse.equalsIgnoreCase(new StringBuilder(strToRevrse).reverse().toString());
I'm new to java and I'm taking up your question as a challenge to improve my knowledge as well so please forgive me if this does not answer your question well:
import java.util.ArrayList;
import java.util.List;
public class PalindromeRecursiveBoolean {
public static boolean isPalindrome(String str) {
str = str.toUpperCase();
char[] strChars = str.toCharArray();
List<Character> word = new ArrayList<>();
for (char c : strChars) {
word.add(c);
}
while (true) {
if ((word.size() == 1) || (word.size() == 0)) {
return true;
}
if (word.get(0) == word.get(word.size() - 1)) {
word.remove(0);
word.remove(word.size() - 1);
} else {
return false;
}
}
}
}
If the string is made of no letters or just one letter, it is a
palindrome.
Otherwise, compare the first and last letters of the string.
If the first and last letters differ, then the string is not a palindrome
Otherwise, the first and last letters are the same. Strip them from the string, and determine whether the string that remains is a palindrome. Take the answer for this smaller string and use it as the answer for the original string then repeat from 1.
The only string manipulation is changing the string to uppercase so that you can enter something like 'XScsX'
check this condition
String string="//some string...//"
check this...
if(string.equals((string.reverse())
{
it is palindrome
}
public static boolean istPalindrom(char[] word){
int i1 = 0;
int i2 = word.length - 1;
while (i2 > i1) {
if (word[i1] != word[i2]) {
return false;
}
++i1;
--i2;
}
return true;
}
import java.util.Scanner;
public class FindAllPalindromes {
static String longestPalindrome;
public String oldPalindrome="";
static int longest;
public void allSubstrings(String s){
for(int i=0;i<s.length();i++){
for(int j=1;j<=s.length()-i;j++){
String subString=s.substring(i, i+j);
palindrome(subString);
}
}
}
public void palindrome(String sub){
System.out.println("String to b checked is "+sub);
StringBuilder sb=new StringBuilder();
sb.append(sub); // append string to string builder
sb.reverse();
if(sub.equals(sb.toString())){ // palindrome condition
System.out.println("the given String :"+sub+" is a palindrome");
longestPalindrome(sub);
}
else{
System.out.println("the string "+sub+"iss not a palindrome");
}
}
public void longestPalindrome(String s){
if(s.length()>longest){
longest=s.length();
longestPalindrome=s;
}
else if (s.length()==longest){
oldPalindrome=longestPalindrome;
longestPalindrome=s;
}
}
public static void main(String[] args) {
FindAllPalindromes fp=new FindAllPalindromes();
Scanner sc=new Scanner(System.in);
System.out.println("Enter the String ::");
String s=sc.nextLine();
fp.allSubstrings(s);
sc.close();
if(fp.oldPalindrome.length()>0){
System.out.println(longestPalindrome+"and"+fp.oldPalindrome+":is the longest palindrome");
}
else{
System.out.println(longestPalindrome+":is the longest palindrome`````");
}}
}
Hi i am trying to write a palindrome method but am getting the wrong results
public static boolean isPalindrome(String input){
int b=input.length();
int []array=new int[b];
for(int i=0;i<array.length;i++){
array[i]=Integer.parseInt(input);}
for(int i=0;i<(array.length)/2;i++){
if(!(array[i]==array[array.length-1-i])){
return false;}
}
return true;
}
}
If you put the String into a StringBuilder you can use the .reverse() method. then just check if the 2 are equal.
StringBuilder input = new StringBuilder("helloolleh");
StringBuilder value = input.reverse();
if(value.toString().equals(input.toString()){
//process
}
You can go for the simpler method to check for palindrome.
Use the StringBuilder class and use the .reverse() method to reverse the string and then check for palindrome test.
StringBuilder value1= new StringBuilder("nitin");
StringBuilder value2 = input.reverse();
if(value1.toString().equals(value2.toString()){
System.out.println("This is a palindrome string ..");
}
Or you can go by this way also ..
public static boolean isPalindrome(String word) {
int left = 0;
int right = word.length() -1;
while (left < right) {
if (word.charAt(left) != word.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
Not sure why you are using Integer.Parse().
Try something like this (mostly following the logic from the question)
public static boolean isPalindrome(String input) {
char[] array = input.toCharArray();
for (int i = 0; i < (array.length) / 2; i++) {
if (!(array[i] == array[array.length - 1 - i])) {
return false;
}
}
return true;
}
You can use two "pointers" one starting from the beginning of the string and one from the end, and move them in opposite directions checking that characters are equals; as soon as you find a difference you know your string is not palindromic; conversely, if you don't find differences you know the string is palindromic:
public static boolean isPalindome(String input) {
char[] cs = input.toCharArray();
for (int i = 0, j = cs.length - 1; i < j; i++, j--) {
if (cs[i] != cs[j])
return false;
}
return true;
}
import java.util.Scanner;
public class Test_String {
private static boolean IsPalindrome(String s)
{
StringBuffer str1 = new StringBuffer(s);
StringBuffer str2 = str1.reverse();
if(s.equalsIgnoreCase(str2.toString()))
return true;
else
return false;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter a String to be checked as Palindrome ");
String in = scan.nextLine();
if(IsPalindrome(in))
System.out.println("\nEntered String is a Palindrome ");
else
System.out.println("\nEntered String is NOT a Palindrome ");
}
}