使用java流的字母大小写排列

Posted

技术标签:

【中文标题】使用java流的字母大小写排列【英文标题】:Letter Case Permutation using java streams 【发布时间】:2020-12-23 22:08:00 【问题描述】:

如何使用 Java 流根据给定的字符串输入查找字母大小写的所有差异?

巩固我对 Java Streams 的理解。我正在使用 java 流解决 leetcode 简单的问题。我对如何使用流解决这个回溯问题感到困惑。我特别困惑如何将一个字符映射两次,即小写和大写。

Input: S = "a1b2"
Output: ["a1b2","a1B2","A1b2","A1B2"]

Stream.of(S.split(""))
      .map(str -> str.toUpperCase()) // this will upper case only
      .map(str -> str.toLowerCase()) // this will lower case only. how to use both?
      .collect(Collectors.toList()); //how do i concatenate strings before adding into list 

为英语不好提前道歉

【问题讨论】:

【参考方案1】:

正如 rzwitserloot 所说,这种问题通常不会使用流进行攻击,但是我会尝试解决您对问题的疑问:

对于具有大写和小写字母的流,您可以使用如下内容:

Stream.of(input.split(""))
    .filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
    .flatMap(str -> Stream.of(str, str.toUpperCase())) // Flatten the stream with both letters
    .collect(Collectors.toList())

如果您想在映射流中的值后连接列表中的字符串,而不是使用Collectors.toList(),您可以像这样使用Collectors.joining()

Stream.of(input.split(""))
    .filter(c -> Character.isLetter(c.charAt(0))) // Filter only letters
    .flatMap(str -> Stream.of(str, str.toUpperCase()))
    .collect(Collectors.joining()) // this collector can receive a delimiter if you want to join them separated by comman for example.

现在对于有问题的问题,您不需要字母的大写和小写版本,只需从输入单词中过滤字母并开始将单词中的字母替换为大写字母版本,这可能是一个可能的解决方案:

    public static void main(String[] args) 
        String input = "a1b2";
        // Output: ["a1b2","a1B2","A1b2","A1B2"];

        Set<String> result = new HashSet<>();
        result.add(input);
        Stream.of(input.split(""))
                .filter(c -> Character.isLetter(c.charAt(0)))
                .forEach(c -> result.addAll(
                        result.stream().map(str -> 
                            if (!str.equals(input.toUpperCase())) 
                                return str.replaceFirst(c, c.toUpperCase());
                            
                            return str;
                        ).collect(Collectors.toSet()))
                );
        System.out.println(result);
    

【讨论】:

感谢代码和解释。这并不能处理所有的测试用例。我也添加了小写条件,但大多数情况下仍然失败。我的主要动机是找出流是否可以简化回溯等问题所需的通常冗长且视觉上令人困惑的意大利面条代码。这和命令式代码一样复杂。我想值得一试。再次感谢。【参考方案2】:

您可以使用 flatmap 来做到这一点,但您的输出将是 ["a", "A", "1", "b", "B", "2"],这与您想要的完全不同。请注意,您的输出会迅速变大;输入中的每个字母的输出数量加倍。这与流甚至不匹配。

一般来说,您想要在这里做的事情是不可能的,或者需要弯曲工具,这类似于试图用锤子在三明治上涂抹黄油。你可能可以,但你为什么要在大火中这样做?这不会提高你使用锤子的技能。

【讨论】:

谢谢,我真的很好奇,想确认一下流是否有办法简化这个问题和其他回溯问题。 Steam 无法解决回溯问题。

以上是关于使用java流的字母大小写排列的主要内容,如果未能解决你的问题,请参考以下文章

文巾解题 784. 字母大小写全排列

784. 字母大小写全排列

LeetCode 0784. 字母大小写全排列:二进制枚举

python-leetcode784-子集字母大小写全排列

python 排序的基本用法。例如按字母顺序排列的大小写。

文巾解题 784. 字母大小写全排列