当前位置: 首页 > 知识库问答 >
问题:

Codingbat挑战:使用流API实现镜像

司迪
2023-03-14

给定CodingBat的任务镜像:

给定一个字符串,请在给定字符串的开头和结尾处查找镜像(向后)字符串。

换句话说,在给定字符串的最开始,以及在字符串的最末尾以相反的顺序(可能重叠)出现零个或多个字符。例如,字符串"abXYZba"具有镜像结尾"ab"

示例:

mirrorEnds("abXYZba")  →  "ab"
mirrorEnds("abca")     →  "a"
mirrorEnds("aba")      →  "aba"

我对此任务的解决方案如下:

public String mirrorEnds(String str) {
  String result = "";
  
  if (str.length() % 2 != 0) {
    for (int i = 0; i < str.length() / 2; i++) {
      if (str.charAt(i) == str.charAt(str.length() - i - 1)) {
        result += "" + str.charAt(i);
      } else {
        break;
      }
    }
    
    if (result.length() == str.length() / 2) {
      String strEnd = new StringBuilder(result).reverse().toString();
      result += "" + str.charAt(str.length() / 2) + strEnd;
    } 
  }
  
  if (str.length() % 2 == 0) {
    for (int i = 0; i < str.length() / 2; i++) {
      if (str.charAt(i) == str.charAt(str.length() - i - 1)) {
        result += "" + str.charAt(i);
      } else {
        break;
      }
    }
    
    if (result.length() == str.length() / 2) {
      String strEnd = new StringBuilder(result).reverse().toString();
      result += strEnd;
    }
  }
  
  return result;
}

是否可以使用Stream API解决此问题?

共有3个答案

邓兴为
2023-03-14

由于您有意要求此问题的流解决方案,这可能是寻找最大的索引i,其中第一个i字符匹配最后一个i字符颠倒,i长度()/2开始,并通过递减i继续,直到它达到0。

只有当给定的字符串不是回文时,才能应用前面的算法。事实上,在这种情况下,可以立即返回字符串本身。

public static String mirrorEnds(String str) {
    if (str.equals(new StringBuilder(str).reverse().toString())) {
        return str;
    }

    OptionalInt maxLen = IntStream.iterate(str.length() / 2, i -> i >= 0, i -> i - 1)
            .filter(i -> str.substring(0, i).equals((new StringBuilder(str.substring(str.length() - i))).reverse().toString()))
            .max();

    return maxLen.isPresent() ? str.substring(0, maxLen.getAsInt()) : null;
}
ab
a
aba

这是一个测试代码的链接:

https://www.jdoodle.com/iembed/v0/rUL

夹谷晋
2023-03-14

使用IntStream是可行的。range()在单流语句中。

为了创建一个单行程序,我们需要Java 9引入的takeWhile()的帮助takeWhile()是一种所谓的短cercuit操作,即它将在与给定谓词不匹配的第一个元素之后中断。

public static String mirrorEnds(String str) {
    
    return IntStream.range(0, str.length())
        .takeWhile(i -> str.charAt(i) == str.charAt(str.length() - 1 - i))
        .map(str::codePointAt)
        .collect(StringBuilder::new,
            StringBuilder::appendCodePoint,
            StringBuilder::append)
        .toString();
}

由于CodingBat仍然在Java8,它的编译器会抱怨上面的代码。

@Holger提出的一个非常好、简单的兼容Java 8的解决方案。

它查找开头和结尾字符之间第一个不匹配的索引,并从最开始的0到不匹配的索引生成一个子字符串。

如果findFirst()返回一个空的可选值,即给定字符串是回文且没有不匹配,则将通过orElse()提供给定字符串的长度。

下面的代码通过了CodingBat的所有测试。

public String mirrorEnds(String str) {
        
        int mismatch = IntStream.range(0, str.length() / 2)
            .filter(i -> str.charAt(i) != str.charAt(str.length() - 1 - i))
            .findFirst()
            .orElse(str.length());
        
        return str.substring(0, mismatch);
    }

注意:由于CodingBat不允许导入,为了在这个站点上运行上面的代码,您需要使用所谓的类的完全限定名。util。流动IntStream

姜明贤
2023-03-14

我认为流API不会给您带来任何优势。但是,您可以像这样优化代码

  public String mirrorEnds(String string) {
    StringBuilder result = new StringBuilder();

    for (int i = 0; i < string.length(); i++) {
        if (string.charAt(i) == string.charAt(string.length() - i - 1)) {
            result.append(string.charAt(i));
        } else {
            break;
        }
    }
    return result.toString();
}
 类似资料:
  • 给定CodingBat中的任务sameEnds: 如果数组开头和结尾的数字组相同,则返回true。例如,对于,n=0和n=2的endpoint相同,n=1和n=3的endpoint相同。您可以假设n在0范围内。。nums。长度(含)。 我对这个问题的解决方案通过了绝大多数测试,但不是所有测试: 我的问题如下: 如何修复我的解决方案 是否可以使用流API解决此任务

  • 给定来自CodingBat的任务sumNumbers sumNumbers: 给定一个字符串,返回字符串中出现的数字之和,忽略所有其他字符。数字是一行中一个或多个数字字符的序列。(注意:Character.isDigit(char)测试字符是否为字符“0”、“1”、…、'9'. 整数parseInt(string)将字符串转换为int.) 我对这个问题的解决方案如下: 是否可以使用流API解决此问

  • 给定来自CodingBat的zeroFront notAlone任务: 返回一个数组,该数组包含与给定数组完全相同的数字,但重新排列以使所有零都在数组的开头分组。非零数字的顺序并不重要。因此变为。您可以修改并返回给定数组或制作一个新数组。 我对这个问题的解决方案在某些情况下会抛出ArrayIndexOutOfBoundsException: 我的问题如下: 如何解决我的问题? 如何使用Stream

  • 给定CodingBat中的任务notAlone: 如果数组中的元素前后都有值,并且这些值与它不同,那么我们会说它是“单独的”。返回给定数组的一个版本,其中给定值的每个单独实例都被其左侧或右侧较大的值替换。 我对这个问题的解决方案通过了绝大多数测试,但不是所有测试: 我的问题如下: 如何解决我的问题? 是否可以使用Stream API解决此任务? 测试结果

  • 如果每个Kafka消息属于一个特定的会话,如何管理会话关联,以便同一个Spark执行器看到链接到一个会话的所有消息? 如何确保属于会话的消息被Spark executor按照在Kafka中报告的顺序处理?我们能以某种方式实现这一点而不对线程计数施加限制并导致处理开销(如按消息时间戳排序)吗? 何时检查会话状态?在执行器节点崩溃的情况下,如何从最后一个检查点恢复状态?在驱动程序节点崩溃的情况下,如何