I want to write a java method to return true if a string is a palindrome.
Here is what I have so far:
String palindrome = "...";
boolean isPalindrome = palindrome.equals(
new StringBuilder(palindrome).reverse().toString());
My problem with this is that it does not consider a word like: Race car to be a palindrome.
Doc, note, I dissent. A fast never prevents a fatness. I diet on cod.
What is the best way to test if this is a palindrome, with case insensitivity and ignoring punctuation.
Use this regex to remove all punctuation and spaces and convert it to lower case
String palindrome = "..." // from elsewhere
boolean isPalindrome = palindrome.replaceAll("[^A-Za-z]", "").toLowerCase().equals(new StringBuilder(palindrome.replaceAll("[^A-Za-z]", "").toLowerCase()).reverse().toString());
Try this ..
public static void main(String[] args) {
boolean notPalindrome = false;
String string = "Doc, note, I dissent. A fast never prevents a fatness. I diet on cod";
string = string.replaceAll("[^a-zA-Z]+","").toLowerCase();
char[] array = string.toCharArray();
for(int i=0, j=array.length-1; i<j; i++, j--) {
if(array[i] != array[j]) {
notPalindrome = true;
break;
}
}
System.out.println(string + " is palindrome? " + !notPalindrome);
}
Use the below regex, to keep even numeric characters in the Palindrome, if needed. Else, you can just remove the 0-9 from the regex.
String palindrome = "..." // from elsewhere
String regex = "[^A-Za-z0-9]";
boolean isPalindrome = palindrome.equals(new StringBuilder(palindrome.replaceAll(regex, "").toLowerCase()).reverse().toString());
Here is a non regex solution.
public class so4
{
public static void main(String args[])
{
String str = "Doc, note, I dissent. A fast never prevents a fatness. I diet on cod";
char c[] =str.toCharArray();
String newStr="";
for(int i=0;i<c.length;i++)
{
if( (c[i]>=65 && c[i]<=90) || (c[i]>=97 && c[i]<=122)) //check ASCII values (A-Z 65-90) and (a-z 97-122)
{
newStr = newStr + c[i];
}
}
boolean isPalindrome = newStr.toLowerCase().equals(new StringBuilder(newStr.toLowerCase()).reverse().toString());
System.out.println(isPalindrome);
}
}
convert to lower case
use a regex to remove everything but letters
reverse the string using a StringBuilder
compare the strings for equality
Code:
/**
* Returns true if s is a palindrome, ignoring whitespace
* punctuation, and capitalization. Returns false otherwise.
*/
public boolean isPalindrome(String s) {
String forward = s.toLowerCase().replaceAll("[^a-z]", "");
String reverse = new StringBuilder(forward).reverse().toString();
return forward.equals(reverse);
}
For more info, see the documentation for String and StringBuilder:
String.toLowerCase()
String.replaceAll()
StringBuilder.reverse()
You can also find it by googling "Java 7 String" and clicking the first result.
Related
For example, if the given string is "HELLO world", the output should be true as the string has satisfied at least one lowercase letter condition.
try {
Pattern pattern = Pattern.compile("^\w*[a-z]\w*$");
Matcher matcher = pattern.matcher(password);
result = matcher.matches();
} catch (Exception e) {
//print something
}
It is not the cleanest solution, but looping through the String like this would also get you the result you want. This function returns true when the string holds one not capital letter.
It doesn't use regex but it also gives you the option to check the String characters for other things you need to verify.
private static boolean checkString(String str) {
char ch;
boolean lowerCaseFlag = false;
for(int i=0;i < str.length();i++) {
ch = str.charAt(i);
if (Character.isLowerCase(ch)) {
lowerCaseFlag = true;
}
}
return lowerCaseFlag;
}
INPUT : 123ABC458
OUTPUT : 321ABC854
public static void main(String []args){
String str="123ABC564";
int count=0;
int ans=0;
int firstindex=0;
char[] ch = str.toCharArray();
for(int i=0;i<ch.length;i++){
if(Character.isDigit(ch[i])){
if(ans==0){
firstindex=i;
}
count++;
}
else{
int lastindex=count+firstindex-1;
while(firstindex<lastindex){
char temp=ch[firstindex];
ch[firstindex]=ch[lastindex];
ch[lastindex]=temp;
firstindex++;
lastindex--;
}
ans=0;
count=0;
firstindex=0;
}
}
for (char c : ch){
System.out.print(c);
}
}
}
Can anyone tell me what's wrong with this code
The output which I am getting using this code is 12BA3C564
You can use the Java regex API and StringBuilder to solve it easily. The regex, \d+ specifies one or more digits. Using the Java regex API, you find the numbers, their start position and the end positions which you can use to build the required string.
Demo:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Tests
String[] samples = { "123ABC458", "123ABC458XYZ", "123ABC458XYZ367", "ABC123XYZ", "ABC123XYZ" };
for (String s : samples)
System.out.println(numbersInverted(s));
}
static String numbersInverted(String str) {
StringBuilder sb = new StringBuilder();
Matcher matcher = Pattern.compile("\\d+").matcher(str);
int lastInitialPos = 0;
while (matcher.find()) {
int start = matcher.start();
String inverted = new StringBuilder(matcher.group()).reverse().toString();
sb.append(str.substring(lastInitialPos, start)).append(inverted);
lastInitialPos = matcher.end();
}
if (sb.length() == 0) // If no number was found
return str;
else
return sb.append(str.substring(lastInitialPos)).toString();
}
}
Output:
321ABC854
321ABC854XYZ
321ABC854XYZ763
ABC321XYZ
ABC321XYZ
ONLINE DEMO
Here is a concise version using string splitting:
String input = "123ABC458";
String[] parts = input.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
StringBuilder sb = new StringBuilder();
for (String part : parts) {
if (part.matches("\\d+")) {
StringBuilder num = new StringBuilder(part);
sb.append(num.reverse());
}
else {
sb.append(part);
}
}
System.out.println(sb.toString()); // 321ABC854
The splitting operation used above generates a string array of either numbers or letters. Then, we iterate that array and selectively reverse the number strings using StringBuilder#reverse.
This task can be implemented without regular expressions, splitting the input string into substring etc. merely with the help of StringBuilder::insert(int offset, char c) and StringBuilder::append(char c) using simple index calculation for insert:
public static String revertDigits(String str) {
if (str == null || str.isEmpty()) {
return str;
}
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0, j = 0, n = str.length(); i < n; i++) {
char c = str.charAt(i);
if (Character.isDigit(c)) {
sb.insert(j, c); // append in "reverse" mode
} else {
sb.append(c);
j = i + 1; // store the last position of a non-digit
}
}
return sb.toString();
}
Test:
String str="123ABC564";
System.out.println(str + '\n' + revertDigits(str));
Output
123ABC564
321ABC465
Can anyone tell me what's wrong with this code
I believe I have spotted two bugs in your code:
You are never setting ans to anything else than 0. So your if condition ans==0 will always be true. If I have understood the purpose of that variable correctly, you may want to replace it with a boolean called something like insideNumber and set it to true when you detect a digit and to false when you detect that a char is not a digit. Your if statement then becomes if (insideNumber) …
You don’t take a number at the end of your string into account. You can check this statement by appending a letter to your string and see that 564 will then be reversed into 465. To reverse a trailing number correctly: after your loop again check whether you were inside a number, and if so, reverse the last number from firstindex up to the end of the string.
You can get all the numbers from the string as the first move, and then replace the input with the reversed string of the numbers. Example:
public static void main(String[] args)
{
String input = "123ABC458";
Matcher m = Pattern.compile("\\d+").matcher(input);
while(m.find())
input = input.replace(m.group(), new StringBuilder(m.group()).reverse());
System.out.println(input);
}
As an alternative solution, from Java 9 you could also make use of Matcher#replaceAll and reverse every match for 1 or more digits.
String result = Pattern.compile("\\d+")
.matcher("123ABC458")
.replaceAll(m -> new StringBuilder(m.group()).reverse().toString());
System.out.println(result);
Output
321ABC854
Java demo
This question already has answers here:
Check string for palindrome
(42 answers)
Closed 3 years ago.
I've been asked in class to determine whether a sentence string (ignoring the upper/lower cases, punctuations, and spaces) is a palindrome or not, and return true/false accordingly.
I've already had a look at several of the discussions here relating to palindrome strings, but I still can't seem to figure out what exactly is wrong with my code, especially because it works in some cases but not others.
In class sentence I have prive String mySentence and private int myNumWords. Regarding the static boolean isPalindrome, I was encouraged to try recursion but I thought to try iteration first.
//Constructor. Creates sentence from String str.
// Finds the number of words in sentence.
//Precondition: Words in str separated by exactly one blank.
public Sentence( String str )
{
mySentence = str;
int count = 0;
for(int k = 0; k<str.length(); k++)
{
if(str.substring(k,k+1).equals(" "))
count++;
}
myNumWords = count + 1;
}
public int getNumWords()
{
return myNumWords;
}
public String getSentence()
{
return mySentence;
}
//Returns copy of String s with all blanks removed.
//Postcondition: Returned string contains just one word.
private static String removeBlanks( String s )
{
return s.replaceAll(" ", "");
}
//Returns true if mySentence is a palindrome, false otherwise.
public boolean isPalindrome()
{
boolean palindrome = true;
String sentence = removeBlanks(mySentence);
String newsentence = removePunctuation(sentence);
int indice1 = 0;
int indice2 = newsentence.length() - 1;
while(indice1 < indice2)
{
if(newsentence.charAt(indice1)!= newsentence.charAt(indice2))
palindrome = false;
indice1++;
indice2--;
}
return palindrome;
}
//Precondition: s has no blanks, no punctuation, and is in lower case.
//Returns true if s is a palindrome, false otherwise.
private static boolean isPalindrome( String s, int start, int end )
{
boolean palindrome = true;
String sentence = removeBlanks(s);
String newsentence = removePunctuation(sentence);
int indice1 = 0;
int indice2 = newsentence.length() - 1;
while(indice1 < indice2)
{
if(newsentence.charAt(indice1)!= newsentence.charAt(indice2))
palindrome = false;
indice1++;
indice2--;
}
return palindrome;
}
//Returns copy of String s with all letters in lowercase.
//Postcondition: Number of words in returned string equals
// number of words in s.
private static String lowerCase( String s )
{
return s.toLowerCase();
}
//Returns copy of String s with all punctuation removed.
//Postcondition: Number of words in returned string equals
// number of words in s.
private static String removePunctuation( String s )
{
return s.replaceAll("\\p{Punct}", "");
}
For instance, for "A Santa lived as a devil at NASA" as my input, I'm supposed to get "true", but keep returning "false".
if you use new Sentence("A Santa lived as a devil at NASA").isPalindrome() then you foget do lowerCase
I'm having some problem with a simple program I'm working on, I just need to ask the user if he wants the regular price or the sale price. And he needs to respond in a string value. Now I know that I just have to use if(price.equals("sale") == true). But the problem comes if I want the user to type something that has spaces in the words, example: if(price.equals("regular price") == true) when I the user types in "regular price" I don't get a response I wanted.
I'm also learning Java by the way.
You can determine if a string contains a word like this:
if (price.toLowerCase().contains("regular"))
If you want to get fancy, you can use regex to match a whole word (eg not "irregular"):
if (price.matches("(?i).*\\bregular\\b.*"))
java equals() method/function works perfectly with the spaces too. Also you don't need to compare the result with true/false. If two string is equal then equals() will automatically return true else it will return false.
public class MyClass {
public static void main(String args[]) {
String a = "A B C";
if(a.equals("A B C")){
System.out.println("YES");
}
else{
System.out.println("NO");
}
}
}
I tested the following program and it returned true while the string has spaces in it.
You want to compare strings with spaces right?
Then you can first compare their lengths, then
If string contains space split it by it, again compare lengths, next check every string.
If it not contains space, just use equals once, here what i come up with:
class cmp {
public static void main(String[] args) {
String s = "test some";
String s2 = "test some";
String s3 = "test not";
String s4 = "testxsome";
System.out.println(cmpStr(s,s2)); // True
System.out.println(cmpStr(s,s3)); // False
System.out.println(cmpStr(s,s4)); // False
}
public static boolean cmpStr(String str1, String str2) {
if (str1.length() != str2.length()) {
System.out.println("Length mismatch.");
return false;
}
if (str1.contains(" ") || str2.contains(" ")) {
String[] a1 = str1.split(" ");
String[] a2 = str2.split(" ");
if (a1.length != a2.length) {
System.out.println("Split Length mismatch.");
return false;
}
for (int i = 0; i < a1.length; i++) {
if (!a1[i].equals(a2[i])) {
System.out.println("One of split mismatch." + a1[i] + " " + a2[i] );
return false;
}
}
} else {
if (!str1.equals(str2)) {
System.out.println("Regular equals returns false.");
return false;
}
}
return true;
}
}
Here I see three methods
Remove all the spaces and hidden characters from the string and check
String input = "regular price";
input = input.replaceAll("\\s+","");
if(price.equals(input))
{
//your code here
}
Check whether the word contains keywords
if (price.toLowerCase().contains("regular"))
Create a regular expression to match your words
I'm trying to create a palindrome tester program for my AP Java class and I need to remove the white spaces in my code completely but it's not letting me do so.
import java.util.Scanner;
public class Palin{
public static boolean isPalindrome(String stringToTest) {
String workingCopy = removeJunk(stringToTest);
String reversedCopy = reverse(workingCopy);
return reversedCopy.equalsIgnoreCase(workingCopy);
}
public static String removeJunk(String string) {
int i, len = string.length();
StringBuffer dest = new StringBuffer(len);
char c;
for (i = (len - 1); i >= 0; i-=1) {
c = string.charAt(i);
if (Character.isLetterOrDigit(c))
{
dest.append(c);
}
}
return dest.toString();
}
public static String reverse(String string) {
StringBuffer sb = new StringBuffer(string);
return sb.reverse().toString();
}
public static void main(String[] args) {
System.out.print("Enter Palindrome: ");
Scanner sc = new Scanner(System.in);
String string = sc.next();
String str = string;
String space = "";
String result = str.replaceAll("\\W", space);
System.out.println(result);
System.out.println();
System.out.println("Testing palindrome:");
System.out.println(" " + string);
System.out.println();
if (isPalindrome(result)) {
System.out.println("It's a palindrome!");
} else {
System.out.println("Not a palindrome!");
}
System.out.println();
}
}
Any help would be greatly appreciated.
Seems like your code is fine except for the following. You are using
String string = sc.next();
which will not read the whole line of input, hence you will lose part of the text. I think you should use the following instead of that line.
String string = sc.nextLine();
If you just want to remove the beginning and ending whitespace, you can use the built in function trim(), e.g. " abcd ".trim() is "abcd"
If you want to remove it everywhere, you can use the replaceAll() method with the whitespace class as the parameter, e.g. " abcd ".replaceAll("\W","").
Use a StringTokenizer to remove " "
StringTokenizer st = new StringTokenizer(string," ",false);
String t="";
while (st.hasMoreElements()) t += st.nextElement();
String result = t;
System.out.println(result);
I haven't actually tesed this, but have you considered the String.replaceAll(String regex, String replacement) method?
public static String removeJunk (String string) {
return string.replaceAll (" ", "");
}
Another thing to look out for is that while removing all non-digit/alpha characters removeJunk also reverses the string (it starts from the end and then appends one character at a time).
So after reversing it again (in reverse) you are left with the original and it will always claim that the given string is a palindrome.
You should use the String replace(char oldChar, char newChar) method.
Although the name suggests that only the first occurrence will be replaced, fact is that all occurrences will be replaced. The advantage of this method is that it won't use regular expressions, thus is more efficient.
So give a try to string.replace(' ', '');