The easiest way is to scroll through the characters of String with a for simple, but if you really want to do recursive, come on...
First of all, this function is not exactly recursive:
public static char funcao (String texto, int indice){
if (indice == 0){
return texto.charAt(indice);
} else {
funcao(texto, indice - 1);
return texto.charAt(indice);
}
}
I mean, you even call the function within itself, but you don’t use the result of this call for anything.
The line funcao(texto, indice - 1); calls the function, but its return is not assigned to any variable, which makes this call useless. And in the end you call texto.charAt(indice), which is exactly the same as what is done inside the if (indice == 0). That is, this function always returns texto.charAt(indice).
There is no reason to take the character of the position X recursively, because the method charAt already returns this character directly. We can then discard this function.
To recursively check the characters of a String are lower case letters, we can consider the following:
- if the
String is empty, the result is zero
- if the
String is not empty, the result is the sum of two things:
1 or 0 (depending on whether the first character is lowercase or not)
- the total of lower case characters of the remainder of
String (from the second character onwards)
An example: if the String for Abc and apply the above algorithm, as would be?
- to
String is empty? No, then let’s go to the next step
- the first character (
A) is it tiny? No, so the partial result is zero.
- now I check the rest of the
String (bc)
- the first character (
b) is it tiny? Yes, so the partial result of this step (that is, of the piece bc) is 1
- now I check the rest of the
String (c)
- the first character (
c) is it tiny? Yes, so the partial result of this step (that is, of the piece c) is 1
- now I check the rest of the
String (to String empty, because no more characters)
- as the
String is empty, the partial result of this step is zero.
Adding up the partial results of each step, the result is 2.
The code would look like this:
public static int contaLetrasMinusculas(String texto) {
// se a String for vazia, retorna zero
if (texto.isEmpty()) {
return 0;
}
// verifica se o primeiro caractere da String é minúsculo
char primeiro = texto.charAt(0);
// se for minúsculo, "c" é igual a 1, senão é zero
int c = Character.isLowerCase(primeiro) ? 1 : 0;
// retorna "c" + a contagem do restante da string
return c + contaLetrasMinusculas(texto.substring(1));
}
Some examples of use:
System.out.println(contaLetrasMinusculas("")); // 0
System.out.println(contaLetrasMinusculas("A")); // 0
System.out.println(contaLetrasMinusculas("b")); // 1
System.out.println(contaLetrasMinusculas("aBcdEFGHiJ@1-")); // 4
Of course you can make it more succinct, but then you see if it becomes less readable/ more difficult to understand:
public static int contaLetrasMinusculas(String texto) {
if (texto.isEmpty()) {
return 0;
}
return (Character.isLowerCase(texto.charAt(0)) ? 1 : 0)
+ contaLetrasMinusculas(texto.substring(1));
}
Unicode
The above code works well for our alphabet. But to work with any Unicode characters, we must make some modifications. For more details on how Unicode works, I recommend oracle tutorial and this question.
In general, Unicode allows characters that do not fit in one char (and are stored internally in two chars - the so-called surrogate pair). So use this approach of charAt does not work for these characters.
And instead use char, we use codepoints (which is the numeric code that all characters have within Unicode).
If you want a more general solution that works with any Unicode characters, the code looks like this:
static int contaLetrasMinusculas(String texto) {
if (texto.isEmpty()) {
return 0;
}
// primeiro Unicode codepoint da String
int primeiro = texto.codePointAt(0);
int c = Character.isLowerCase(primeiro) ? 1 : 0;
// Character.charCount verifica se o codepoint ocupa um ou dois chars
return c + contaLetrasMinusculas(texto.substring(Character.charCount(primeiro)));
}
The code keeps working for the previous cases:
System.out.println(contaLetrasMinusculas("")); // 0
System.out.println(contaLetrasMinusculas("A")); // 0
System.out.println(contaLetrasMinusculas("b")); // 1
System.out.println(contaLetrasMinusculas("aBcdEFGHiJ@1-")); // 4
But now it also works for other Unicode characters, such as (DESERET SMALL LETTER LONG I), which corresponds to Unicode Codepoint 66600 and is considered lowercase:
// DESERET SMALL LETTER LONG I http://www.fileformat.info/info/unicode/char/10428/index.htm
String s = new String(Character.toChars(66600));
System.out.println(contaLetrasMinusculas("aA" + s + "Bb")); // 3
is not duplicate? https://answall.com/q/331602/28595
– user28595
Does it have to be recursive? Because it doesn’t seem to be such a problem.
– Gustavo Fragoso
@Gustavofragoso In exercise asks to use recursion but does not specify to what. I’m learning about recursion yet.
– water
@Article In my view it is not about duplicate because I am dealing with other different types of results.
– water