This question already has answers here:
Check string for palindrome
(42 answers)
Closed 1 year ago.
I am trying to write a method to check if a given word is a palindrome, but as of now it does not work. I suspect the error lies within the if-statement and the fact that you don't compare objects such as strings with == but instead with equals, is that right? However Java does not allow me to write: if (firstHalf.charAt(i).equals(secondHalf.charAt(j))), so what can I do to make it work? Are there other errors in the code?
public static boolean isPalindrome(String string) {
String firstHalf = string.substring(0, string.length() / 2);
String secondHalf = string.substring(string.length() / 2, string.length());
for (int i = 0; i <= firstHalf.length(); i++) {
for (int j = secondHalf.length(); j <= 0; j--) {
if (firstHalf.charAt(i) == secondHalf.charAt(j)) {
return true;
}
}
}
return false;
}
Why not do it this way?
public static boolean isPalindrome(String string){
StringBuilder sb = new StringBuilder(string);
sb.reverse();
return sb.toString().equals(string);
}
Your character test was backwards. All of the comparisons have to be equal for the String to be a palindrome.
Also, splitting the String is unnecessary. You can logically split the String with two indices.
Try this code.
public static boolean isPalindrome(String string) {
int frontIndex = 0;
int backIndex = string.length() - 1;
while (frontIndex < backIndex) {
if (string.charAt(frontIndex++) != string.charAt(backIndex--)) {
return false;
}
}
return true;
}
you can make each character a String like so
String s1 = "" + c1;
and then compare them with .equals(s1, s2)
Or you can use the Character class which is a wrapper around primitive character.
That would also enable you to use c1.equals(c2)
Related
So I have a public static method 'getWithoutLeadingZeroes', which gets passed a String and simply needs to return it without any zeroes prefixing the string of numbers.
Now, I know that I need to iterate through the string until I find the first non-zero char in the string, but I'm not exactly sure how to take the point where the method finds the non-zero char and start copying the remainder of the String into a new String, then returning it.
Here's what I have so far:
public static String getWithoutLeadingZeroes(String s) {
boolean notZero = false;
char[] t = new char[x];
for(int i = 0; i<s.length(); i++){
if(s.charAt(i) == 0){
notZero = false;
} else {
notZero = true;
}
if(notZero = true){
for(int j = index.charAt(i))
}
return ""; //to be completed
}
I created a boolean variable to stop the loop once it hits the non-zero char and I'm pretty positive the first half of the code is accurate, but its the creating of the new String to be returned that I'm a bit stuck on. Any suggestions would be welcome.
You are NOT stopping your loop.
You could do that using the break keyword.
And: your comparison is wrong, it should read
if (... == '0'
You could use String#substring(int beginIndex) instead:
public static String getWithoutLeadingZeroes(String s) {
int i = 0;
while (i < s.length() && s.charAt(i) == '0') i++;
return s.substring(i);
}
How about the following way?
public static String getWithoutLeadingZeroes(String s) {
while(s.startsWith('0'))
s = s.substring(1);
return s;
}
This should do it
String nmbrStr = "1001234";
String cleanedStr = nmbrStr; // this way the whole number will be
// returned if in has no leading zeroes
for (int i = 0; i < nmbrStr.length(); i++) {
if (nmbrStr.charAt(i) != '0') {
cleanedStr = nmbrStr.substring(i);
break;
}
}
System.out.println(cleanedStr);
You can also use Integer.parseInt(nmbrStr) which is a lot cleaner
A simple solution.
public static String getWithoutLeadingZeroes(String stringOfNumbers) {
return String.valueOf(Long.parseLong(stringOfNumbers));
}
Another alternative solution:
public String getWithoutLeadingZeroes(String str) {
int from = 0;
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i) == '0'){
from = i;
}else{
break;
}
}
return str.substring(from+1);
}
You can then make it a little bit more robust by implementing try/catch blocks and possibly along with cases that deal with unexpected input e.g null parameter or a zero-length string etc.
Given two small String of different length and one full String. Check if the full String is merged from two small String.
Example1: Input - "beautiful", "bauful", "eti" Output - true
Example2: Input - "beautiful", "baufl", "eti" Output - false
That means the characters in small String 1 and small String 2 are in the same order as in full String.
Here is my code:
public class StringMerger {
public static boolean isMerge(String s, String part1, String part2) {
StringBuilder sb = new StringBuilder();
int minLength = Math.min(part1.length(), part2.length());
int maxLength = Math.max(part1.length(), part2.length());
for(int i = 0; i < minLength; i++){
sb.append(part1.charAt(i)).append(part2.charAt(i));
}
for(int i = minLength; i < maxLength; i++){
if(part1.length() >= part2.length()) sb.append(part1.charAt(i));
else sb.append(part2.charAt(i));
}
String temp = sb.toString();
return (temp.equalsIgnoreCase(s)) ? true : false;
}
}
But I have only solve with: Input - "beautiful", "batfl", "euiu" Output - true. This is only one of that' cases. So how to solve it?
Checkout the below solution, you are welcome to break it
Edit1 Fix bug: the bug is not due to the space, it is because when there is a character match in both small strings, the algorithm need to examine which character to take by checking both alternatives
Edit2 Reduce unnecessary depth first search to improve efficiency
public class StringMerger {
public static void main(String[] args) {
System.out.println(isMerge("beautiful", "bauful", "eti")); // true
System.out.println(isMerge("beautiful", "baufl", "eti")); // false
System.out.println(isMerge("bbbbb", "bbb", "bb")); // true
System.out.println(isMerge("xyzxyz", "xyz", "xyz")); // true
System.out.println(isMerge("xyzxyz", "xyz", "xyzd")); // false
System.out.println(isMerge("backstreetboy", "beetb", "ackstroy")); // true
System.out.println(isMerge("Can we merge it? Yes, we can!", "Cn w riYes n!", "aemege t? , weca")); //true
System.out.println(isMerge("beautifulxyzx", "baufulx", "etixyz")); // true
}
public static boolean isMerge(String s, String part1, String part2) {
if (s.length() != part1.length() + part2.length()) return false;
int part1Counter = 0;
int part2Counter = 0;
int fullStrLen = s.length();
int fullStrCounter = 0;
while (fullStrCounter < fullStrLen) {
boolean part1match = part1Counter < part1.length() && s.charAt(fullStrCounter) == part1.charAt(part1Counter);
boolean part2match = part2Counter < part2.length() && s.charAt(fullStrCounter) == part2.charAt(part2Counter);
if (part1match && part2match) { // if find a match in both substring, we need to find out whichever way works
boolean decision1 = isMerge(s.substring(fullStrCounter + 1), part1.substring(part1Counter + 1), part2.substring(part2Counter));
if (decision1) return decision1; // no need to check the second branch if the first branch matches
boolean decision2 = isMerge(s.substring(fullStrCounter + 1), part1.substring(part1Counter), part2.substring(part2Counter + 1));
return decision2;
}
if (part1match) {
++part1Counter;
++fullStrCounter;
} else if (part2match) {
++part2Counter;
++fullStrCounter;
} else {
return false;
}
}
return true;
}
}
Here's a shorter method. It makes use of Arrays.
private static boolean isMerge(String original, String one, String two){
String combinedStrings = one + two;
char[] mergedStrings = combinedStrings.toCharArray();
char[] originalString = original.toCharArray();
Arrays.sort(mergedStrings);
Arrays.sort(originalString);
return Arrays.equals(mergedStrings, originalString);
}
A possible brute-force starting algorithm, without giving you the solution for your homework:
Walk the word String looking for matches in each candidate String.
If there is no match (or both Strings are exhausted), then return False.
If there is a match, move the index for this candidate String.
If we exhaust the word String and all candidate Strings, return True.
I'm hand-waving past the edge conditions here, which would ideally be caught by tests.
It occurs to me that this class should be able to generate candidate Strings from any word String, meaning that you could even make the class symmetric.
This question already has answers here:
How can I check if a single character appears in a string?
(16 answers)
Closed 7 years ago.
I am trying to make a method called Baller(String str, char chr) which should return a boolean if the word contains the character. In the main method I have:
public static void main(String[] args) {
Balling ball= new Balling ();
System.out.println( ball.contains("Baller", 'a'));
System.out.println( ball.contains("Baller", 'A'));
}
What I did was this but it did not work:
public boolean contains(String str, char chr ) {
if(str.length() == chr) {
return true;
}
else {
return false;
}
}
What could be the problem?
ANSWER
public boolean contains(String str, char chr ) {
for(int i = 0; i < str.length(); i++)
if(str.charAt(i) == chr)
return true;
return false;
}
}
The problem is that string length is compared to character value:
str.length() == chr
What you should use if the indexOf String method
public boolean contains(String str, char chr) {
return str.indexOf(chr) != -1;
}
You are testing if the length of the String is equal to some char. This will perhaps work if your String is of length zero and your character == 0 or perhaps if your String is of length one and you compare it to the character with the numeric value of 1. In other words: Almost never.
You never return false. So all your string contain all your characters.
String has an indexOf( character ) method. use that. See documentation.
I want to write a boolean method subString() to judge if string s1 is the substring of s2.
The requirement is only to use charAt() and length() methods of String.
E.g.
Substring("abc","abcd")-> true
Substring("at","cat")->true
Substring("ac","abcd")->false
indexOf() cannot be used.
Here is what I got so far.
public class Q3 {
public boolean subString(String str1, String str2) {
String s1 = str1.toLowerCase();
String s2 = str2.toLowerCase();
for (i = 0; i < s1.length; i++) {
for (j = 0; j < s2.length; j++) {
if (s1.charAt(i) == s2.charAt(j))
return true;
}
}
return false;
}
}
Test class is :
public class Q3test {
public static void main (String arg[]){
Q3 Q3object = new Q3();
System.out.println(Q3object.Substring("ac","abcd"));
}
}
It fails subString("ac","abcd") as it returns true.
Your code returns true if the first character matches. You need all the characters of the first String to be contained in a substring of the second String.
EDIT:
My original code was wrong. Here's the correct code :
public static boolean subString(String str1, String str2)
{
String s1 = str1.toLowerCase();
String s2 = str2.toLowerCase();
for (int offset = 0; offset <= s2.length() - s1.length(); offset++) {
int i = 0;
for (; i < s1.length(); i++){
if(s1.charAt(i) != s2.charAt(i+offset)) {
break;
}
}
// found a substring that starts at the current offset
if (i == s1.length())
return true;
}
return false;
}
The contains method of the string class should do
For examples please refer to this: http://www.tutorialspoint.com/java/lang/string_contains.htm
You should also check if the characters are in order, and are in-next to each other. Your code only checks for the existence of characters.
public static boolean subString(String a, String b) {
int checker = 0;
String sub = a.toLowerCase();
String supr = b.toLowerCase();
// loops through all the characters of superstring
for (int sp = 0; sp < supr.length(); sp++) {
// finds the first character of the substring
if (supr.charAt(sp) == sub.charAt(0)) {
// loops through the characters of the substring
for (int sb = 0, tmp = sp; sb < sub.length(); sb++, tmp++) {
if (supr.charAt(tmp) == sub.charAt(sb))
checker++; // increments checker for every char match
}
// resets checker if not all characters for sub is equal to super based on their order
if (checker != sub.length())
checker = 0;
}
// match occurred if all characters of the substring is present in the superstring,
// in which they are in the same order, and all are existing consecutively
if (checker == sub.length())
return true;
}
return false;
}
Let's say we have:
public static void main(String[] args) {
System.out.println(subString("abc", "abcd"));
System.out.println(subString("at", "cat"));
System.out.println(subString("ac", "abcd"));
}
The output will be:
true
true
false
I need an algorithm that verify with the fastest possible execution time, if a string is a palindrome ( the string can be a proposition with uppercase or lowercase letter, spaces etc.). All of this in Java. I got a sample :
bool isPalindrome(string s) {
int n = s.length();
s = s.toLowerCase();
for (int i = 0; i < (n / 2) + 1; ++i) {
if (s.charAt(i) != s.charAt(n - i - 1)) {
return false;
}
}
return true;
}
I transformed the string in lowercase letter using .toLowerCase() function, but I don't know how much it affects the execution time .
And as well I don't know how to solve the problem with punctuation and spaces between words in a effective way.
I think you can just check for string reverse, not?
StringBuilder sb = new StringBuilder(str);
return str.equals(sb.reverse().toString());
Or, for versions earlier than JDK 1.5:
StringBuffer sb = new StringBuffer(str);
return str.equals(sb.reverse().toString());
This avoids any copying. The functions isBlank and toLowerCase are rather unspecified in your question, so define them the way you want. Just an example:
boolean isBlank(char c) {
return c == ' ' || c == ',';
}
char toLowerCase(char c) {
return Character.toLowerCase(c);
}
Don't worry about the costs of method calls, that's what the JVM excels at.
for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {
while (isBlank(s.charAt(i))) {
i++;
if (i >= j) return true;
}
while (isBlank(s.charAt(j))) {
j--;
if (i >= j) return true;
}
if (toLowerCase(s.charAt(i)) != toLowerCase(s.charAt(j))) return false;
}
return true;
Try to benchmark this... I'm hoping mu solution could be the fastest, but without measuring you never know.
Your solution seems just fine when it comes to effectiveness.
As for your second problem, you can just remove all spaces and dots etc before you start testing:
String stripped = s.toLowerCase().replaceAll("[\\s.,]", "");
int n = stripped.length();
for (int i = 0; i < (n / 2) + 1; ++i) {
if (stripped.charAt(i) != stripped.charAt(n - i - 1)) {
...
Effective is not the same of efficient.
Your answer is effective as long you consider spaces, special characters and so on. Even accents could be problematic.
About efficiency, toLowerCase is O(n) and any regexp parsing will be O(n) also. If you are concerning about that, convert and compare char by char should be the best option.
Here is my try:
public static boolean isPalindrome(String s)
{
int index1 = 0;
int index2 = s.length() -1;
while (index1 < index2)
{
if(s.charAt(index1) != s.charAt(index2))
{
return false;
}
index1 ++;
index2 --;
}
return true;
}
Here's some insight to my way of detecting a palindrome using Java. Feel free to ask question :) Hope I could help in some way....
import java.util.Scanner;
public class Palindrome {
public static void main(String[]args){
if(isReverse()){System.out.println("This is a palindrome.");}
else{System.out.print("This is not a palindrome");}
}
public static boolean isReverse(){
Scanner keyboard = new Scanner(System.in);
System.out.print("Please type something: ");
String line = ((keyboard.nextLine()).toLowerCase()).replaceAll("\\W","");
return (line.equals(new StringBuffer(line).reverse().toString()));
}
}
In normal cases :
StringBuilder sb = new StringBuilder(myString);
String newString=sb.reverse().toString();
return myString.equalsIgnoreCase(newString);
In case of case sensitive use :
StringBuilder sb = new StringBuilder(myString);
String newString=sb.reverse().toString();
return myString.equals(newString);