java计数字母递归方法

qcuzuvrc  于 2021-06-29  发布在  Java
关注(0)|答案(7)|浏览(380)

所以程序必须计算字符串的字母数。我不允许使用循环,递归循环除外。
方法必须如下所示:

static int numberOf(String text, char characterToCount)

输入:
ba(字符串)和b(字符)
输出:
4
到目前为止,我的代码就是这样的(我得到了stackoverflow):

static int numberOf(String text, char characterToCount) {
 int i = 0;
 int erg = 0;
 if (text.length() != 0) {
   if (i != text.length()) {
     if (text.charAt(i) == characterToCount) {
       i++;
       erg++;
       numberOf(text, characterToCount);
     } else {
       i++;
       numberOf(text, characterToCount);
     }
   } else {
     return erg;
   }
 }

 return 0;
}

编辑
我只允许使用 String.charAt 以及 String.length

1cklez4t

1cklez4t1#

所以我想我有办法了。可能不是很好,但很管用。感谢您的帮助:)

public class CountLetters {

public static void main(String[] args) {

    print("Bitte geben Sie den Text ein: ");
    String text = readString();
    text = toLowerCase(text, 0);
    print("Bitte geben Sie ein Zeichen ein: ");
    String zeich = readString();
    zeich = toLowerCase(zeich, 0);
    if (zeich.length() > 1) {
        throw new PR1Exception("Bitte nur einen Buchstaben eingeben. ");
    }
    char zeichen = zeich.charAt(0);

    if (zeichen > 0 && zeichen < 65 && zeichen > 90 && zeichen < 97 && zeichen > 123) {
        throw new PR1Exception("Bitte nur Buchstaben eingeben.");
    }
    int anzahl = numberOf(text, zeichen);

    println("-> " + anzahl);

}

static String toLowerCase(String text, int i) {
    String lowerText = "";
    if (i == text.length()) {
        return lowerText;
    } else if (text.charAt(i) < 'a') {
        return lowerText += (char) (text.charAt(i) - 'A' + 'a') + toLowerCase(text, i + 1);
    } else {
        return lowerText += text.charAt(i) + toLowerCase(text, i + 1);
    }
}

static int numberOf(String text, char characterToCount) {
    return hilfe(text, characterToCount, 0, 0);
}

static int hilfe(String t, char ch, int i, int a) {

    if (t.length() == a) {
        return i;
    } else if (t.charAt(a) == ch) {
        return hilfe(t, ch, i + 1, a + 1);
    } else {
        return hilfe(t, ch, i, a + 1);
    }

}
vwkv1x7d

vwkv1x7d2#

wjs的答案看起来不错,但如果您想要更简单的解决方案,这可能也会有所帮助。
解决方案中的问题是 i 以及 erg 在一个调用堆栈中,下一个递归调用堆栈没有看到/使用它们,因为它们是局部变量,每个堆栈都有自己的i和erg副本。每次调用时,它们总是初始化为0 numberOf 方法。
如果不允许使用子字符串,那么一种方法是使用一个额外的变量来保存所比较文本中的位置索引。
但是在这样做时,您可能必须修改方法的签名(如果您不想使用类级静态变量)。既然您已经提到您的方法必须只有两个参数(text,chartocount),那么实现这一点的一种方法就是使用helper方法(包含额外的 index 参数)并且您的方法可以调用它。

static int numberOf(String text, char characterToCount) {
    return helper(text, characterToCount, 0);
}

static int helper(String text, char charToCount, int index) {
    if (text.isEmpty() || index == text.length()) return 0;

    int countCharOnRight = helper(text, charToCount, index+1);

    return (text.charAt(index) == charToCount) ? 1 + countCharOnRight : countCharOnRight;
}
zsbz8rwp

zsbz8rwp3#

另一种解决方案是利用java 11引入的本地类:

static int numberOf(String text, char characterToCount){
    class CharCounter {
        int counter = -1;
        int numberOf(String text, char characterToCount) {
            counter++;
            if(counter == text.length()) return 0;
            else if(text.charAt(counter) == characterToCount) return 1 + numberOf(text, characterToCount);
            else return numberOf(text, characterToCount);
        }
    }
    return new CharCounter().numberOf(text, characterToCount);
}
hrirmatl

hrirmatl4#

递归的思想是在某些条件之后多次调用同一个函数/方法。一个好的方法是调用相同的函数,但每次都要减少要检查的字符串。

public class StringUtils {

    public int numberOf(String text, char characterToCount) {
       int count = 0;
       if (text.length() != 0) {
           if(text.charAt(0) == characterToCount) { //Only increment when is the same character
               count++; 
           }
           count = count + numberOf(text.substring(1, text.length()), characterToCount); //Do a substring but remove the first character
       }

       return count;
   }
}

测试

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class StringUtilsTest {

    @Test
    public void should_count_all_the_ocurrences() {

        //Given
        StringUtils utils = new StringUtils();
        String sentence = "</www></palabraRandom></www></palabraRandom></palabraRandom></www>";

        //When
        int output = utils.numberOf(sentence, '>');

        //Then
        assertEquals(6, output);
    }

}
xmd2e60i

xmd2e60i5#

问题是在调用方法时没有减少文本,因此长度永远不会减少到0。这是你应该做的。请注意,不需要向方法传递索引。每次只需将文本减少1,并检查第一个字符是否与目标字符相等。

public static void main(String[] args) {
    System.out.println(numberOf("ksjssjkksjssss", 's'));
}

static int numberOf(String text, char characterToCount) {
    if (text.isEmpty()) {
        return 0;
    }

    if (text.charAt(0) == characterToCount) {
        // call method and add 1 since you found a character
        return numberOf(text.substring(1), characterToCount) + 1;
    }
    // just call the method.
    return numberOf(text.substring(1), characterToCount);

}

上面的指纹

8

好的,这是我的修改版本,以满足您的使用要求 String.length 以及 String.charAt . 字符实际上是16位的,所以我使用高位字节来存储当前索引。我为每个递归调用增加索引,以保持搜索的当前位置。当我加上 256 我要加的角色 1 到高位字节。

static int numberOf(String text, char ch) {
    // stop when index exceeds text length
    if (ch >> 8 >= text.length()) {
        return 0;
    }
    if (text.charAt((ch >> 8)) == (ch & 0xff)) {
        return numberOf(text, (char)(ch + 256)) + 1;
    }
    return numberOf(text, (char)(ch + 256));
}

这将无法在某些宽度大于8位的字符集上工作。

pxyaymoc

pxyaymoc6#

什么

static int numberOf(String text, char characterToCount) {
    return numberOfRecursive(text, characterToCount, 0);
}

// Recursive helper function
static int numberOfRecursive(String text, char characterToCount, int index) {

    if (index == text.length()) // Abort recursion
        return 0;

    if (text.charAt(index) == characterToCount) // check char at index, then check next recursively
        return numberOfRecursive(text, characterToCount, index + 1) + 1;
    else
        return numberOfRecursive(text, characterToCount, index + 1);
}

为什么?
大多数递归问题都需要一个helper函数,它实际执行递归部分。它将从具有初始值的原始函数调用,这里使用文本、字符和起始位置0。
然后,递归函数需要一个中止条件,这是我通过绑定检查提供的。如果递归到达字符串的末尾,我们就终止。
最后递归函数根据递归调用进行计算。在这里,如果索引位置的字符是要计数的字符,那么我们在结果中加1。如果不是,我们继续计数,不加1。
我希望我能帮上忙。

crcmnpdw

crcmnpdw7#

如果到达返回0的结尾,可以使用索引变量。否则,如果是letter或0,则返回1。

public class Main {
    public static void main(String[] args) {
        System.out.println(numberOf("Hello World-1234", 'o'));
    }

    private static int numberOf(String text, char characterToCount) {
        if (!text.isEmpty()) {
            return numberOf(text.substring(1), characterToCount) + (text.charAt(0) == characterToCount ? 1 : 0);
        }
        return 0;
    }
}

编辑:不带 substring ```
public class Main {
public static void main(String[] args) {
System.out.println(numberOf("Hello World-1234", 'o'));
}

private static int numberOf(String text, char characterToCount) {
    if (text.isEmpty()) {
        return 0;
    }
    char[] chars = text.toCharArray();
    char[] newChars = new char[chars.length - 1];
    System.arraycopy(chars, 1, newChars, 0, newChars.length);

    return numberOf(new String(newChars), characterToCount) + (chars[0] == characterToCount ? 1 : 0);
}

}

相关问题