【问题标题】:Recursively count characters in a string in JAVA递归计算JAVA中字符串中的字符
【发布时间】:2020-03-15 10:24:49
【问题描述】:

如果我有一个字符串 abcabcabcabc 和一个 int N 3,我会尝试返回 "cccc"。我知道如何使用for 循环来做到这一点,但我不知道如何使用递归来做到这一点。

非常感谢任何帮助。

这是我目前所拥有的:

public String everyNth(String s, int n){
    if(s.length() % n == 0){
        return s.charAt(n-1) + "";
    }
    else {
        return everyNth(s.substring(n, s.length()), n);
    }
}

到目前为止,它只打印“c”而不是“cccc”。

【问题讨论】:

  • 从描述你想要做什么开始。 public String cccc() {return "cccc";}你不需要递归。
  • @LowKeyEnergy 我正在尝试打印字符串“s”中的“nth”字符,从 1 而不是 0 开始,这就是为什么 n = 3 == c 而不是 a。
  • 如果 N=3 并且 s="abcabcabcabc" 那么“字符串 s 中的第 N 个字符”就是“c”......所以根据您自己的解释,您需要一个只打印“ c"。
  • 输入s = "abcabcabcabc"(长度为12)和n = 3,所以s.length() % n = 12 % 3 = 0,也就是说return s.charAt(n-1) + "";使得方法返回"c"

标签: java string recursion substring


【解决方案1】:

这是一种方式

public String everyNth(String s, int n) {
    if (s.length() >= n) {
        return s.charAt(n - 1) + everyNth(s.substring(n), n);
    } else {
        return "";
    }
}

您可以制定一个不需要对返回结果做任何事情的尾递归版本。像 Scala 这样的一些语言可以使用它来优化以避免有限的堆栈深度(和 StackOverflow 异常),但不是 java,如 for now

public String everyNthAcc(String s, String acc, int n) {
    if (s.length() >= n) {
        return everyNthAcc(s.substring(n), acc + s.charAt(n - 1), n);
    } else {
        return acc;
    }
}

@Test
public void tryIt() {
    assertEquals("cccc", everyNthAcc("abcabcabcabc","", 3));
}

因此,就目前而言,每个堆栈帧的大小越小,递归就越深,这应该会使其更进一步,但有点奇怪:

public class EveryNth {

    String value = "abcabcabcabc";
    StringBuilder sb = new StringBuilder();
    int nth = 3;

    @Test
    public void tryIt() {
        everyNthAgain(nth);
        assertEquals("cccc", sb.toString());
    }

    public void everyNthAgain(int curr) {
        if (curr <= value.length()) {
            sb.append(value.charAt(curr - 1));
            everyNthAgain(curr + nth);
        }
    }
}

【讨论】:

    【解决方案2】:

    这是一种带有一点参数检查的方法。这个想法是与递归调用一起发送一些状态。每次调用都会修改下一次调用的状态(startingIndex)。当状态超过某个条件时,递归停止。当递归调用展开时,结果字符串被组装。

    public static void main(String... args) {
        System.out.println(everyNth("abcabcabcabc", 3));
    }
    
    public static String everyNth(String s, int n) {
        if (n < 0) {
            return "";
        }
        return everyNth(s, n, n - 1);
    }
    
    public static String everyNth(String s, int n, int startingIndex) {
        if (startingIndex < s.length()) {
            return s.charAt(startingIndex) + everyNth(s, n, startingIndex + n);
        }
        return "";
    }
    

    【讨论】:

      【解决方案3】:

      这是一种不依赖于传递索引的方法,这似乎更多的是循环而不是递归。

      它使用终止条件,在每次调用时更改起始参数,并使用返回值堆栈来返回结果。如果需要,可以将 char 参数替换为硬编码的“c”。

      public String countChar(String s, char c) {
          if (s.length() == 0) return "";
          return (s.charAt(0) == c ? c : "") + countChar(s.substring(1),c);
      }
      

      【讨论】:

      • 返回所有出现的 c,但不是每个第 n 个字符。
      • 哇,我想我真的没有仔细阅读这个问题。
      • 哟,我并不陌生;)
      猜你喜欢
      • 2013-07-21
      • 2017-04-28
      • 2017-10-18
      • 2014-03-31
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多