Reputation: 105
I have a problem in this recursion exercise.
The exercise is to test whether the array of characters has only uppercase or lowercase and only then return true; otherwise if there are both lowercase and uppercase letters, return false.
The code below always returns true.
I try to put a variable to count every time there is a large or small signal and then if the amount is equal to the array so it is true otherwise it is not true; but it does not give me that. It is a Boolean function and call recursion is not giving me the amount of the variable.
The code:
public static boolean Arr(char[] arr, int length) {
if (length == -1)
return true;
boolean flag = Character.isUpperCase(arr[length]);
if (flag)
return true;
return Arr(arr, length - 1);
}
Upvotes: 1
Views: 372
Reputation: 4091
When dealing with boolean algebra, it's always worth it to write some unit to help us verify our work:
import static org.junit.Assert.*;
import org.junit.Test;
public class CharactersSpec {
@Test
public void itShouldBeTrueWhenAllCharsAreUppercase() {
String input = "HELLO";
assertEquals(true, Characters.isSameCase(input.toCharArray()));
}
@Test
public void itShouldBeTrueWhenAllCharsAreLowercase() {
String input = "hello";
assertEquals(true, Characters.isSameCase(input.toCharArray()));
}
@Test
public void itShouldBeFalseWhenOneCharIsLowercase() {
String input = "HeLLO";
assertEquals(false, Characters.isSameCase(input.toCharArray()));
}
@Test
public void itShouldBeFalseWhenOneCharIsUppercase() {
String input = "hEllo";
assertEquals(false, Characters.isSameCase(input.toCharArray()));
}
}
Then one can implement the method. I wouldn't implement it with recursion but it seems to be a requirement from your assignment:
import java.util.Arrays;
public final class Characters {
public static boolean isSameCase(char[] chars) {
return isSameCase(chars, false, false);
}
private static boolean isSameCase(char[] chars, boolean uppercaseFound, boolean lowercaseFound) {
if(chars.length == 0) {
return true;
}
lowercaseFound |= Character.isLowerCase(chars[0]);
uppercaseFound |= Character.isUpperCase(chars[0]);
return !(lowercaseFound && uppercaseFound) && isSameCase(Arrays.copyOfRange(chars, 1, chars.length),
uppercaseFound,
lowercaseFound);
}
}
Note a few things:
public
method only takes a char[]
as parameter, so that the caller don't have to bother with recursion detailsWithout the assignment's constraints I would implement this method as follow
public static boolean isSameCase(String input) {
return input.equals(input.toLowerCase()) || input.equals(input.toUpperCase());
}
Note that:
String
over char[]
in Java (it is more convenient)Upvotes: 0
Reputation: 636
See if this works
public static boolean Arr(char[] arr, int length) {
if (length == -1)
return true;
boolean flag = Character.isUpperCase(arr[length]);
if (flag)
return Arr(arr, length - 1);
else
return false;
}
Upvotes: 1
Reputation: 19855
Does this meet your needs?
The public
front end just takes a character array, and invokes the private
back end with starting values for the parameters that end users shouldn't have to worry about.
public static boolean sameCase(char[] ary) {
return sameCase(ary, 0, ary.length - 1);
}
The back end seeks to split the current segment of the array into two subsegments—halving the problem keeps the rate of growth of the stack as O(log #chars)
rather than O(#chars)
. If the current segment has fewer than two characters, then trivially all characters have the same case. Otherwise, check that each subsegment has characters that are all of the same case, and if so, check that the cases of the two subsegments are the same using XOR and a trick.
private static boolean sameCase(char [] ary, int first, int last) {
int len = last - first + 1;
int mid = first + len / 2;
return len < 2 ||
(sameCase(ary, first, mid - 1) && sameCase(ary, mid, last) &&
(Character.isUpperCase(ary[first]) ^ Character.isLowerCase(ary[last])));
}
Note that by ANDing the recursive calls, logical short-circuiting speeds things up on average here.
Upvotes: 0
Reputation: 26926
You need an additional parameter in the function and an additional exit condition:
A second approach is to start not from the first char, but from the second and check for same case between current and prior character.
Upvotes: 1