1

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);
}
3
  • I am not sure why you use this "if (flag == true) return true; " As flag is already is boolean you can use like if(flag). And please debug and let us know which condition return true for you. Commented Jun 9, 2016 at 12:32
  • I think with the path you are on, you are going to have issues when you get to the all upper OR all lower part. Your recursive function needs to communicate either what the caller is expecting, or the recursive calls found. The latter return wouldn't be a plain Boolean, but something that indicated uc,lc, or mixed. Commented Jun 9, 2016 at 12:39
  • 1
    Besides: please take a second to read about java coding style conventions. Your method name "Arr()" is a) violating those conventions ... and b) really really bad, as it doesn't tell anything about the method (names are important: they tell you what the things are/are doing that they denote!) Commented Jun 9, 2016 at 12:41

4 Answers 4

1

You need an additional parameter in the function and an additional exit condition:

  • Additional parameter: Last character read was lower or uppercase
  • Additional test to exit: if current char has not the same case of last char exits with false

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes.... I already added this second approach as a possibility while you were writing
1

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;
}

Comments

0

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.

Comments

0

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:

  • The only public method only takes a char[] as parameter, so that the caller don't have to bother with recursion details
  • I have decided to subarray instead of passing an index so that the method signature keeps 3 parameters (I always foster readability over performance, first)

Without 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:

  • I prefer to manipulate String over char[] in Java (it is more convenient)
  • I would avoid recursion as possible since I believe this practice is not well-suited in Java (most programmers are not familiar with and the language provides other ways to loop)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.