To check if string is palindrome using recursion? - java

There is something wrong with my code as one the testcase in my assignment is coming out wrong, giving me runtime error when I submit the code online. That testcase could be any String. I believe that everything is fine with the code as I have checked it manually for many testcases.
HERE IS THE CODE
public static boolean isStringPalindrome(String input) {
if(input.length()==0 || input.length()==1)
return true;
int first = 0;
int last = input.length()-1;
if(input.charAt(first) != input.charAt(last))
return false;
String str="";
for(int i=first+1;i<last;i++){
str = str+input.charAt(i);
}
boolean sa = isStringPalindrome(str);
return sa;
}
Sample Input
racecar
Output
true
Sample Input
pablo
Output
false

Your code appears to be overly complicated for recursively testing if the String is a palindrome. Something like,
public static boolean isStringPalindrome(String input) {
if (input == null) {
return false;
} else if (input.isEmpty() || input.length() == 1) {
return true;
}
int len = input.length() - 1;
return input.charAt(0) == input.charAt(len) //
&& isStringPalindrome(input.substring(1, len));
}
Is recursive without embedding a for loop. Because if you can do that, you should do something like
public static boolean isStringPalindrome(String input) {
if (input == null) {
return false;
} else if (input.isEmpty() || input.length() == 1) {
return true;
}
int len = input.length();
for (int i = 0; i <= len / 2; i++) {
if (input.charAt(i) != input.charAt(len - 1 - i)) {
return false;
}
}
return true;
}

A simpler way to check for palindrome can be:
public static boolean isPalindrome(String s)
{ if (input == null)
return false;
else if(s.length() == 0 || s.length() == 1)
return true;
/* check for first and last char of String:
* if they are same then do the same thing for a substring
* with first and last char removed. and carry on this
* until you string completes or condition fails.
*/
if(s.charAt(0) == s.charAt(s.length()-1))
return isPalindrome(s.substring(1, s.length()-1));
return false;
}
Update
You are getting runtime error(NZEC) which means non-zero exit code. It means your program is ending unexpectedly. I don't see any reason except that your program doesn't have a null check. Otherwise, I have gone through your code carefully, you are doing the same thing which I have suggested.

Related

What am I doing wrong in this loop?

So for I am trying to make a boolean method that checks if an inputed string is a positive integer. It will return true if it is a positive integer and false if it is anything else. Here is my code:
public static boolean isPositiveInteger(String input) {
int stringLength = input.length();
int index = stringLength-1;
while(index>0) {
index--;
if(input.charAt(0) != '-' && input.charAt(index) >= '0' &&
input.charAt(index) <= '9') {
return true;
}
return false;
}
return false;
}
When the input is the string "fish33" the method will return true instead of false. Why is that?
Your while loop executes only once - return will stop execution. Moreover, you start with second to last, not with last character. Replace your code with this one:
public static boolean isPositiveInteger(String input) {
int stringLength = input.length();
int index = stringLength;
// special case when input is empty string
if (index == 0) {
return false;
}
while(index > 0) {
index--;
// if some of the characters is not digit, return false
if !(input.charAt(index) >= '0' &&
input.charAt(index) <= '9') {
return false;
}
}
// if the while loop does not find any other character, return true
return true;
}
There is no point to make so many manipulations, it can be solved in few lines
public static void main(String[] args) {
System.out.println(isPositiveInteger("1"));
System.out.println(isPositiveInteger("abc"));
}
public static boolean isPositiveInteger(String input) {
try {
Integer i = Integer.parseInt(input);
return i > 0;
}
catch(NumberFormatException nfe){
return false;
}
}

Trying to return true if all the letters in a string are the same

What I have so far:
public boolean allSameLetter(String str)
{
for (int i = 1; i < str.length(); i++)
{
int charb4 = i--;
if ( str.charAt(i) != str.charAt(charb4))
{
return false;
}
if ( i == str.length())
{
return true;
}
}
}
Please excuse any inefficiencies if any; still relatively new to coding in general. Am I lacking some knowledge in terms of using operators and .charAt() together? Is it illogical? Or is my error elsewhere?
Using regex:
return str.matches("^(.)\\1*$");
Using streams:
str.chars().allMatch(c -> c == str.charAt(0));
Other:
return str.replace(String.valueOf(str.charAt(0), "").length() == 0;
You can follow the below steps:
(1) Get the first character (i.e., 0th index)
(2) Check the first character is the same with subsequent characters, if not return false (and comes out from method)
(3) If all chars match i.e., processing goes till the end of the method and returns true
public boolean allSameLetter(String str) {
char c1 = str.charAt(0);
for(int i=1;i<str.length;i++) {
char temp = str.charAt(i);
if(c1 != temp) {
//if chars does NOT match,
//just return false from here itself,
//there is no need to verify other chars
return false;
}
}
//As it did NOT return from above if (inside for)
//it means, all chars matched, so return true
return true;
}
As Andrew said, you are decreasing i within your for loop. You can fix this by changing it to int charb4 = i - 1;. As for making your code more efficient you could condense it down to this.
public boolean allSameLetter(String str) {
for(char c : str.toCharArray())
if(c != str.charAt(0)) return false;
return true;
}
Comment if you don't understand a part of it :)
public boolean allSameLetter(String str)
{
for (int i = 1; i < str.length() -1; i++)
{
if ( str.charAt(i) != str.charAt(i+1))
{
return false;
}
}
return true
}
-1 is there since I am checking the current value in the array, then the next value in the array, thus I need to stop a place earlier.
If the loop if statement is never entered, it will make it far enough into the code to return true
You have to create a for loop that searches through the length of the String - 1. this way the program will not crash because of a 3 letter word with the program trying to get the 4th letter. This is what works for me:
public boolean allSameLetter(String str)
{
for(int i = 0; i< str.length()-1; i++){
if (str.charAt(i) != str.charAt(i+1)){
return false;
}
}
return true;
}
if((new HashSet<Character>(Arrays.asList(s.toCharArray()))).size()==1)
return true;
return false;
This should be enough
The bug is caused by
int charb4 = i--;
this line is equal to
int charb4 = i-1;
i=i-1;
Because of this, your loop will never stop.
The easiest way to fix this
public boolean allSameLetter(String str)
{
for (int i = 1; i < str.length(); i++)
{
if ( str.charAt(i) != str.charAt(i-1))
{
return false;
}
}
}

Rewriting a for loop as recursive method?

I am having trouble rewriting the following code as a recursive method rather than using the for loop. The for loop tests to see if the String 'noSpaces' is a palindrome (the same forwards as it is backwards). The noSpaces String has no punctuation, spaces, or differences in capitalization.
Thanks for the help
public boolean isRegularPalindrome(String noSpaces) {
noSpaces = noSpaces.toUpperCase();
String[] letters = new String[noSpaces.length()];
for (int i = 0; i < letters.length; i++) {
letters[i] = Character.toString(noSpaces.charAt(i));
}
for (int i = 0; i < letters.length / 2; i++) {
if (!letters[i].equals(letters[letters.length - i - 1])) {
return false;
}
}
return true;
}
There you go:
public static boolean isPalindrome(String input) {
if (input.charAt(0) != input.charAt(input.length() - 1)) {
// Missmatch. Not a palindrome!
return false;
} else if (input.length() > 1){
// If there is more to test, continue.
return isPalindrome(input.substring(1, input.length() - 1));
} else {
// All chars were tested, or 1 char input. Palindrome!
return true;
}
}
Writing a recursive algorithm for anything requires base cases. For a palindrome, this would be a string of length 0 or length 1 -- if the string is length 0 or 1, it is a palindrome.
If the base cases aren't met, you check the first character against the last character.
If the characters aren't the same, return false.
If the characters are the same, return the recursive call to the string except for the first and last characters.
The code should look something like this.
public boolean isPalindrome(string str){
if (str.length == 0)
return true;
else if (str.length == 1)
return true;
else if(str.charAt(0) != str.charAt(str.length - 1)
return false;
else
return isPalindrome(str.substring(1, length - 1));
}

Can't figure out how to fix my code

Hi for the past few hours i have been trying to fix my code. The problem is that when I go to check if "" is an integer is returns true when it should be false. I know why this is happening, it is because it doesn't enter the for loop and returns true , but I can't seem to figure out how to make it return false for "". I can provide more info if needed.
public boolean isInteger(String str)
{
for (int x = 0, n = str.length(); x < n; x++)
{
char c = str.charAt(x);
if (c < '0' || c > '9')
{
if (c != 0 || c != '-')
{
return false;
}
}
}
return true;
}
Thank you for spending your time on trying to help me :)
You could check valid input (ie, a string with length = 0) and return false before you ever try the loop. You're correct, though, it's not entering the loop and just returning true.
--edit--
Something like
if (string == null) || (string.length() == 0){
return false
}
In your algorithm, an empty string will always return true. You just need to add a check:
if(str==null || str.length()==0) return false;
Alternatively, you can use this function:
public static boolean isInteger(String str)
{
try
{
Integer.parseInt(str);
return true;
}
catch(NumberFormatException e)
{
return false;
}
}

Validate a String to see if it is an Integer?

Not keen on using the parseInteger solution, it is ugly, and as Joshua Bloch says you should "Use exceptions only for exceptional conditions". Of course, I can use something like block of code below, but it doesn't guarantee it is an Integer.
for (char c : str.toCharArray())
{
if (!Character.isDigit(c)) return false;
}
return true;
"Use exceptions only for exceptional conditions" is a good practice to follow in general, but it's not a hard-and-fast rule. I think that this is one of the cases where using exceptions is better than the alternatives.
Since parseInteger() can return any possible int value, you can't use any other return value to indicate failure. If you know you're never going to process a particular value (such as -1 or -2147483648), you can return that as a sentinel value to indicate a parse failure.
The only alternative is to return a boolean indicating success or failure and to store the parsed value into a parameter. However, since function calls are always pass-by-value in Java, you'd need to create a new class to do this:
public class IntWrapper
{
int value;
}
...
public static boolean myParseInt(String s, IntWrapper outValue)
{
try
{
outValue.value = Integer.parseInt(s);
return true;
}
catch(NumberFormatException e)
{
return false;
}
}
...
IntWrapper value = new IntWrapper();
if (myParseInt(value))
{
// Use value.value
}
else
{
// Parsing failed
}
Given these alternatives, I think the simplest usage is just to use exceptions and deal with them appropriately, even though non-numeric input may not necessary be an "exceptional" condition.
I'd leave it with exception but if you REALLY want solution without exception you can copy method parseInt() from this site with java internal classes and change it a little bit
(You can modify it a little bit more, since you do not need result)
public static false isValidInt(String s, int radix)
throws NumberFormatException
{
if (s == null) {
return false;
}
if (radix < Character.MIN_RADIX) {
return false;
}
if (radix > Character.MAX_RADIX) {
return false;
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else
return false;
if (len == 1) // Cannot have lone "-"
return false;
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
return false;
}
if (result < multmin) {
return false;
}
result *= radix;
if (result < limit + digit) {
return false;
}
result -= digit;
}
} else {
return false;
}
return true;
}
You could use:
public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c <= '/' || c >= ':') {
return false;
}
}
return true;
}
Already answered here: What's the best way to check to see if a String represents an integer in Java?

Categories

Resources